From dede23e8db090d7754e88bb2d084c6f860adc338 Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 15 Apr 2026 23:41:25 +0800 Subject: [PATCH] Add mermaids.sh --- mermaids.sh | 251 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 mermaids.sh diff --git a/mermaids.sh b/mermaids.sh new file mode 100644 index 0000000..0483f49 --- /dev/null +++ b/mermaids.sh @@ -0,0 +1,251 @@ +#!/bin/bash +# ct/mermaidjs.sh - Create and configure a self-hosted Mermaid.js editor LXC + +set -euo pipefail + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +log() { echo -e "${GREEN}[$(date +%H:%M:%S)]${NC} $1"; } +warn() { echo -e "${YELLOW}[$(date +%H:%M:%S)]${NC} $1"; } +die() { echo -e "${RED}[$(date +%H:%M:%S)]${NC} $1"; exit 1; } + +# Ensure root on Proxmox +if [[ $EUID -ne 0 ]]; then + die "This script must be run as root on a Proxmox VE host" +fi + +# Defaults +LXC_HOSTNAME="mermaid" +LXC_ID="" +LXC_MEMORY=512 +LXC_CORES=1 +LXC_DISK="local-lvm" +LXC_TEMPLATE="local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst" +LXC_ROOT_PASSWORD="mermaid" +LXC_IP="" +LXC_NETMASK="24" +LXC_GATEWAY="" +LXC_BRIDGE="vmbr0" + +# Auto-increment VMID +get_next_id() { + local max=0 + for id in $(pct list | awk 'NR>1 {print $1}'); do + ((id > max)) && max=$id + done + echo $((max + 1)) +} + +log "=== Mermaid.js Interactive Editor LXC Setup ===" +log "This creates a self-hosted Mermaid editor with OFFLINE support." + +read -rp "Hostname (default: mermaid): " HOSTNAME_INPUT +[[ -n "$HOSTNAME_INPUT" ]] && LXC_HOSTNAME="$HOSTNAME_INPUT" + +read -rp "Container ID (default: $(get_next_id)): " ID_INPUT +LXC_ID=${ID_INPUT:-$(get_next_id)} + +read -rp "Memory (MB, default: 512): " MEM_INPUT +LXC_MEMORY=${MEM_INPUT:-512} + +read -rp "CPU Cores (default: 1): " CORES_INPUT +LXC_CORES=${CORES_INPUT:-1} + +read -rp "Root Password (default: mermaid): " PASS_INPUT +LXC_ROOT_PASSWORD=${PASS_INPUT:-mermaid} + +read -rp "Disk Storage Pool (default: local-lvm): " DISK_INPUT +LXC_DISK=${DISK_INPUT:-local-lvm} + +read -rp "Network Bridge (default: vmbr0): " BRIDGE_INPUT +LXC_BRIDGE=${BRIDGE_INPUT:-vmbr0} + +read -rp "IP Address (e.g., 192.168.1.60; leave blank for DHCP): " IP_INPUT +LXC_IP="$IP_INPUT" + +if [[ -n "$LXC_IP" ]]; then + read -rp "Netmask (default: 24): " NETMASK_INPUT + LXC_NETMASK=${NETMASK_INPUT:-24} + read -rp "Gateway (blank for none): " GW_INPUT + LXC_GATEWAY="$GW_INPUT" +fi + +NET0_ARGS="name=eth0,bridge=$LXC_BRIDGE" +if [[ -n "$LXC_IP" ]]; then + NET0_ARGS="$NET0_ARGS,ip=$LXC_IP/$LXC_NETMASK" + [[ -n "$LXC_GATEWAY" ]] && NET0_ARGS="$NET0_ARGS,gw=$LXC_GATEWAY" +fi + +# Fail fast if bridge or disk don't exist +pvesm status | grep -q "$LXC_DISK" || die "Storage pool '$LXC_BRIDGE' not found" +ip link show "$LXC_BRIDGE" >/dev/null 2>&1 || die "Bridge '$LXC_BRIDGE' not found" + +# === 1. Create LXC Container === +log "Creating LXC container $LXC_ID ($LXC_HOSTNAME)..." +pct create $LXC_ID $LXC_TEMPLATE \ + -hostname $LXC_HOSTNAME \ + -memory $LXC_MEMORY \ + -cores $LXC_CORES \ + -net0 $NET0_ARGS \ + -rootfs $LXC_DISK:1 \ + -ostype debian \ + -password $LXC_ROOT_PASSWORD \ + -onboot 1 + +# === 2. Start & wait for boot === +log "Starting container..." +pct start $LXC_ID +log "Waiting for container to be reachable..." +for i in {1..40}; do + if pct exec $LXC_ID -- sh -c "ping -c1 127.0.0.1 >/dev/null 2>&1"; then + break + fi + sleep 1 +done + +# === 3. Prepare install script (bundled offline Mermaid) === +log "Deploying Mermaid editor + Caddy..." + +# Generate the install script dynamically (with bundled mermaid.min.js) +pct push $LXC_ID - <<'EOF' /root/mermaid-install.sh +#!/bin/bash +set -euo pipefail + +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +log() { echo -e "${GREEN}[$(date +%H:%M:%S)]${NC} $1"; } + +# 1. Update & install Caddy & deps +log "Updating system..." +apt-get update -qq +apt-get install -y -qq curl wget + +# 2. Download Mermaid.min.js (offline bundled) +log "Downloading Mermaid v10.6.1 (offline)..." +mkdir -p /var/www/mermaid +wget -q https://cdn.jsdelivr.net/npm/mermaid@10.6.1/dist/mermaid.min.js -O /var/www/mermaid/mermaid.min.js + +# 3. Create the editor HTML (self-contained: editor + preview + Mermaid JS) +log "Creating Mermaid editor interface..." +cat > /var/www/mermaid/index.html <<'HTML' + + + + + Self-hosted Mermaid Editor + + + + + + +
+ + +HTML + +# 4. Caddy config (HTTP only — easy; HTTPS in comment) +cat > /etc/caddy/Caddyfile <<'CADDY' +:80 { + root * /var/www/mermaid + file_server + log { + output file /var/log/caddy/access.log + } +} +# Uncomment below for Let's Encrypt HTTPS +# mermaid.yourdomain.com { +# root * /var/www/mermaid +# file_server +# } +CADDY + +# 5. Start & enable Caddy +rc-service caddy start +rc-update add caddy + +# 6. Check if Caddy started +sleep 5 +if curl -sf http://localhost >/dev/null; then + log "✅ Mermaid Editor is live!" +else + warn "Caddy failed — check 'rc-service caddy status' and 'journalctl -u caddy'" + exit 1 +fi + +# 7. Summary +IP=$(hostname -I 2>/dev/null | cut -d' ' -f1) +if [[ -z "$IP" ]]; then + IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}') +fi +log "URL: ${BLUE}http://${IP}${NC}" +log "Root password: ${YELLOW}$LXC_ROOT_PASSWORD${NC}" +log "SSH: ssh root@${IP}" +EOF + +# Push & run the install script inside LXC +log "Installing Mermaid editor..." +pct exec $LXC_ID -- bash /root/mermaid-install.sh + +# === 4. Final summary === +IP=$(pct exec $LXC_ID -- hostname -I 2>/dev/null | cut -d' ' -f1) +[[ -z "$IP" ]] && IP=$(pct exec $LXC_ID -- ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}') + +log "✅ Mermaid Editor LXC ($LXC_ID) ready!" +log "URL: ${BLUE}http://${IP}${NC}" +log "Root password: ${YELLOW}$LXC_ROOT_PASSWORD${NC}" \ No newline at end of file