From e9149c49ff0276e262a8f8fc9c90e8d95b8c4605 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 16 Apr 2026 00:13:19 +0800 Subject: [PATCH] Update mermaids.sh --- mermaids.sh | 274 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 180 insertions(+), 94 deletions(-) diff --git a/mermaids.sh b/mermaids.sh index 434fe2b..8ab6e76 100644 --- a/mermaids.sh +++ b/mermaids.sh @@ -1,4 +1,6 @@ #!/bin/bash +# ct/mermaidjs.sh - Create and configure a self-hosted Mermaid.js editor LXC + set -euo pipefail RED='\033[0;31m' @@ -11,171 +13,255 @@ 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; } -if [[ $EUID -ne 0 ]] || [[ ! -f /etc/pve/nodes ]]; then +# Ensure root on Proxmox VE +if [[ $EUID -ne 0 ]] || ! command -v pct &>/dev/null; then die "This script must be run as root on a Proxmox VE host" fi -LXC_HOSTNAME="mermaid" +# === Configuration Defaults === LXC_ID="" -LXC_MEMORY=256 +LXC_HOSTNAME="mermaid" +LXC_MEMORY=512 LXC_CORES=1 LXC_DISK="local-lvm" -LXC_TEMPLATE="local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst" +LXC_TEMPLATE="local:vztmpl/debian-12-standard_12.0-1_amd64.tar.zst" LXC_ROOT_PASSWORD="mermaid" LXC_IP="" LXC_NETMASK="24" LXC_GATEWAY="" LXC_BRIDGE="vmbr0" +LXC_PORT="80" # HTTP port — change if needed (e.g., 8080) +# 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 + for id in $(pct list | awk 'NR>1 {print $1}'); do + ((id > max)) && max=$id + done echo $((max + 1)) } -log "=== Mermaid Editor LXC Setup (Alpine + Caddy) ===" +log "=== Mermaid.js Interactive Editor LXC Setup (Debian 12) ===" +log "This creates a container with a live-editable Mermaid editor (offline-capable)." + +# === Interactive Prompts === 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: 256): " MEM_INPUT -LXC_MEMORY=${MEM_INPUT:-256} + +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 Pool (default: local-lvm): " DISK_INPUT + +read -rp "Disk Storage Pool (default: local-lvm): " DISK_INPUT LXC_DISK=${DISK_INPUT:-local-lvm} -read -rp "Bridge (default: vmbr0): " BRIDGE_INPUT + +read -rp "Network Bridge (default: vmbr0): " BRIDGE_INPUT LXC_BRIDGE=${BRIDGE_INPUT:-vmbr0} -read -rp "IP (blank for DHCP): " IP_INPUT + +read -rp "HTTP Port (default: 80): " PORT_INPUT +LXC_PORT=${PORT_INPUT:-80} + +read -rp "IP Address (e.g., 192.168.1.60; leave blank for DHCP): " IP_INPUT LXC_IP="$IP_INPUT" -[[ -n "$LXC_IP" ]] && { + +if [[ -n "$LXC_IP" ]]; then read -rp "Netmask (default: 24): " NETMASK_INPUT LXC_NETMASK=${NETMASK_INPUT:-24} - read -rp "Gateway (blank): " GW_INPUT + read -rp "Gateway (blank for none): " GW_INPUT LXC_GATEWAY="$GW_INPUT" -} - -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 Debian 12 LXC container $LXC_ID ($LXC_HOSTNAME)..." -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" \ +# Build network config safely +if [[ -n "$LXC_IP" ]]; then + if [[ -z "$LXC_GATEWAY" ]]; then + warn "IP provided without gateway — using DHCP for gateway" + NET_CONFIG="dhcp=1" + else + NET_CONFIG="ip=$LXC_IP/$LXC_NETMASK,gw=$LXC_GATEWAY" + fi +else + NET_CONFIG="dhcp=1" +fi + +pct create $LXC_ID $LXC_TEMPLATE \ + -hostname $LXC_HOSTNAME \ + -memory $LXC_MEMORY \ + -cores $LXC_CORES \ + -net0 name=eth0,bridge=$LXC_BRIDGE,$NET_CONFIG \ + -rootfs $LXC_DISK:2 \ -ostype debian \ - -password "$LXC_ROOT_PASSWORD" \ - -onboot 1 + -password $LXC_ROOT_PASSWORD \ + -onboot 1 \ + -features nesting=1 \ + -unprivileged 0 log "Starting container..." -pct start "$LXC_ID" -log "Waiting for container to be reachable..." -for i in {1..40}; do - pct exec "$LXC_ID" -- sh -c "ping -c1 127.0.0.1 >/dev/null 2>&1" && break +pct start $LXC_ID + +log "Waiting for container to be reachable (max 60s)..." +for i in {1..60}; do + if pct exec $LXC_ID -- sh -c "ping -c1 127.0.0.1 >/dev/null 2>&1"; then + break + fi sleep 1 done -log "Deploying Mermaid editor (offline + interactive UI)..." -pct exec "$LXC_ID" -- sh -c " - set -euo pipefail - GREEN='\033[0;32m'; NC='\033[0m' - log() { echo -e \"\${GREEN}[\$(date +%H:%M:%S)]\${NC} \$1\"; } +# === 2. Prepare and Deploy Install Script === +log "Deploying Mermaid editor + Caddy..." - # 1. Update + install deps - log 'Updating system...' - apk update >/dev/null 2>&1 - apk add caddy curl >/dev/null 2>&1 +cat > /tmp/mermaid-install.sh <<'EOF' +#!/bin/bash +set -euo pipefail - # 2. Download Mermaid (offline) - log 'Downloading Mermaid v10.6.1...' - mkdir -p /var/www/mermaid - wget -q -O /var/www/mermaid/mermaid.min.js \ - https://cdn.jsdelivr.net/npm/mermaid@10.6.1/dist/mermaid.min.js +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' - # 3. Create editor HTML (split editor + preview) - log 'Creating interactive editor interface...' - cat > /var/www/mermaid/index.html <<'HTMLEOF' +log() { echo -e "${GREEN}[$(date +%H:%M:%S)]${NC} $1"; } + +PORT="${1:-80}" + +# 1. Update & install Caddy + deps +log "Updating system..." +apt-get update -qq +apt-get install -y -qq wget ufw + +# 2. Download Mermaid (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 (dark theme, live preview) +log "Creating Mermaid editor interface..." +cat > /var/www/mermaid/index.html <<'HTML' - + Self-hosted Mermaid Editor - + - -
+ +
-HTMLEOF +HTML - # 4. Caddy config (HTTP) - log 'Configuring Caddy...' - cat > /etc/caddy/Caddyfile <<'CADDYEOF' -:80 { - root * /var/www/mermaid - file_server - log { output file /var/log/caddy/access.log } +# 4. Caddy config (HTTP on $PORT) +log "Configuring Caddy..." +cat > /etc/caddy/Caddyfile </dev/null 2>&1 - rc-update add caddy >/dev/null 2>&1 - sleep 3 +# 5. Start & enable Caddy +rc-service caddy start +rc-update add caddy - if curl -sf http://localhost >/dev/null; then - log 'Mermaid Editor is live!' - else - log 'Caddy may still be starting — check rc-service caddy status' - fi +# 6. Firewall +ufw --force enable 2>/dev/null || true +ufw allow $PORT/tcp 2>/dev/null || true - # 6. Summary - IP=$(hostname -I 2>/dev/null | cut -d' ' -f1) - [[ -z \"$IP\" ]] && IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}') - log \"URL: ${BLUE}http://${IP}${NC}\" - log \"Root password: ${YELLOW}$LXC_ROOT_PASSWORD${NC}\" -" +# 7. Wait + check +log "Waiting for Caddy to start..." +sleep 5 +if curl -sf "http://localhost:$PORT" >/dev/null; then + log "Mermaid Editor is live!" +else + warn "Caddy failed — check 'rc-service caddy status' and 'journalctl -u caddy'" + exit 1 +fi -IP=$(pct exec "$LXC_ID" -- sh -c 'hostname -I 2>/dev/null | cut -d" " -f1') -[[ -z "$IP" ]] && IP=$(pct exec "$LXC_ID" -- sh -c "ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'") +# 8. Output 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}:${PORT}${NC}" +log "Root password: ${YELLOW}$LXC_ROOT_PASSWORD${NC}" +log "SSH: ssh root@${IP}" +EOF + +# Push & run install script +pct push $LXC_ID /tmp/mermaid-install.sh /root/mermaid-install.sh || die "Failed to push script" +pct exec $LXC_ID -- bash /root/mermaid-install.sh "$LXC_PORT" || die "Install failed" + +# Cleanup +rm -f /tmp/mermaid-install.sh + +# === 3. Final Summary === +IP_ADDR=$(pct exec $LXC_ID -- hostname -I 2>/dev/null | cut -d' ' -f1) +[[ -z "$IP_ADDR" ]] && IP_ADDR=$(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 "URL: ${BLUE}http://${IP_ADDR}:${LXC_PORT}${NC}" log "Root password: ${YELLOW}$LXC_ROOT_PASSWORD${NC}" \ No newline at end of file