#!/usr/bin/env bash # Create LXC 5801 (dapp-smom): frontend-dapp build served by nginx. # Usage: ./scripts/deployment/deploy-dapp-lxc.sh [--dry-run] [--skip-create] # --dry-run Print commands only. # --skip-create Use existing container 5801 (only install/build/serve). # Env: PROXMOX_HOST (optional; if unset, run pct on current host), NODE (optional; pct --node), # VMID, HOSTNAME, IP_DAPP_LXC, TEMPLATE, STORAGE, NETWORK, MEMORY_MB, CORES, DISK_GB, # REPO_URL (git URL to clone) or REPO_PATH (local path to copy; no git in container), # ENV_FILE (path to .env for VITE_*). # See: docs/03-deployment/DAPP_LXC_DEPLOYMENT.md set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SMOM_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" # Robust ip-addresses.conf path: override, or proxmox repo layout, or smom-dbis-138-only layout IP_CONFIG_PATH="${IP_CONFIG_PATH:-}" if [[ -n "$IP_CONFIG_PATH" && -f "$IP_CONFIG_PATH" ]]; then source "$IP_CONFIG_PATH" 2>/dev/null || true elif [[ -f "${SMOM_ROOT}/../../config/ip-addresses.conf" ]]; then source "${SMOM_ROOT}/../../config/ip-addresses.conf" 2>/dev/null || true elif [[ -f "${SCRIPT_DIR}/../../../config/ip-addresses.conf" ]]; then source "${SCRIPT_DIR}/../../../config/ip-addresses.conf" 2>/dev/null || true fi VMID="${VMID:-5801}" HOSTNAME="${HOSTNAME:-dapp-smom}" IP="${IP_DAPP_LXC:-192.168.11.58}" GATEWAY="${NETWORK_GATEWAY:-192.168.11.1}" NETWORK="${NETWORK:-vmbr0}" STORAGE="${STORAGE:-local-lvm}" TEMPLATE="${TEMPLATE:-local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst}" MEMORY_MB="${MEMORY_MB:-6144}" CORES="${CORES:-4}" DISK_GB="${DISK_GB:-40}" REPO_URL="${REPO_URL:-}" REPO_PATH="${REPO_PATH:-}" ENV_FILE="${ENV_FILE:-}" PROXMOX_HOST="${PROXMOX_HOST:-}" NODE="${NODE:-}" SSH_OPTS="-o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new" DRY_RUN=false SKIP_CREATE=false for a in "$@"; do [[ "$a" == "--dry-run" ]] && DRY_RUN=true [[ "$a" == "--skip-create" ]] && SKIP_CREATE=true done run_cmd() { if [[ -n "$PROXMOX_HOST" ]]; then ssh $SSH_OPTS root@"$PROXMOX_HOST" "$@" else bash -c "$*" fi } run_pct() { local node_opt="" [[ -n "$NODE" && -z "$PROXMOX_HOST" ]] && node_opt="--node $NODE" if [[ -n "$PROXMOX_HOST" ]]; then ssh $SSH_OPTS root@"$PROXMOX_HOST" "pct $node_opt $*" else pct $node_opt "$@" fi } pct_exec() { run_pct "exec $VMID -- $*" } echo "=== DApp LXC ($VMID) — $HOSTNAME ===" echo "IP: $IP | Memory: ${MEMORY_MB}MB | Cores: $CORES | Disk: ${DISK_GB}G" echo "" if ! $SKIP_CREATE; then if $DRY_RUN; then echo "[DRY-RUN] Would create LXC $VMID on ${PROXMOX_HOST:-local} with hostname=$HOSTNAME, ip=$IP/24" exit 0 fi if run_pct list 2>/dev/null | grep -q " $VMID "; then echo "Container $VMID already exists. Use --skip-create to only install/build/serve." exit 0 fi echo "Creating CT $VMID ($HOSTNAME)..." # When PROXMOX_HOST is set we SSH to that host; do not pass --node (pct runs on that node). node_opt="" [[ -n "$NODE" && -z "$PROXMOX_HOST" ]] && node_opt="--node $NODE" run_cmd "pct create $VMID $TEMPLATE \ --hostname $HOSTNAME \ --memory $MEMORY_MB \ --cores $CORES \ --rootfs $STORAGE:${DISK_GB} \ --net0 name=eth0,bridge=$NETWORK,ip=$IP/24,gw=$GATEWAY \ --nameserver ${DNS_PRIMARY:-1.1.1.1} \ --description 'DApp (frontend-dapp) for Chain 138 bridge. See docs/03-deployment/DAPP_LXC_DEPLOYMENT.md' \ --start 1 \ --onboot 1 \ --unprivileged 0 \ --features nesting=1 \ $node_opt" echo "Waiting for container to boot..." sleep 20 fi if $DRY_RUN; then echo "[DRY-RUN] Would install Node, nginx, clone repo, build, configure nginx." exit 0 fi echo "Installing Node 20, nginx, git, curl..." pct_exec "bash -c 'export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install -y -qq curl git ca-certificates'" pct_exec "bash -c 'curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y -qq nodejs'" pct_exec "apt-get install -y -qq nginx" if [[ -z "$REPO_URL" && -z "$REPO_PATH" ]]; then echo "Neither REPO_URL nor REPO_PATH set. Skipping clone/copy and build." echo "Example: REPO_URL=https://github.com/your-org/smom-dbis-138.git ... or REPO_PATH=/path/to/smom-dbis-138 ... ./scripts/deployment/deploy-dapp-lxc.sh --skip-create" exit 0 fi APP_DIR="/srv/smom-dbis-138" pct_exec "mkdir -p $APP_DIR" if [[ -n "$REPO_PATH" && -d "$REPO_PATH" ]]; then echo "Copying repo from host ($REPO_PATH)..." PARENT="$(cd "$(dirname "$REPO_PATH")" && pwd)" BARE="$(basename "$REPO_PATH")" TARNAME="smom-dbis-138-deploy.tar.gz" TARBALL="/tmp/$TARNAME" (cd "$PARENT" && tar czf "$TARBALL" --exclude="$BARE/node_modules" --exclude="$BARE/.git" --exclude="$BARE/frontend-dapp/node_modules" --exclude="$BARE/frontend-dapp/dist" "$BARE") || { echo "Failed to create tarball"; exit 1; } if [[ -n "$PROXMOX_HOST" ]]; then scp $SSH_OPTS "$TARBALL" root@"$PROXMOX_HOST":/tmp/ run_cmd "pct push $VMID /tmp/$TARNAME /tmp/$TARNAME" pct_exec "bash -c 'rm -rf $APP_DIR && mkdir -p /srv && tar xzf /tmp/$TARNAME -C /srv && rm /tmp/$TARNAME'" run_cmd "rm -f /tmp/$TARNAME" else run_pct push "$VMID" "$TARBALL" "/tmp/$TARNAME" pct_exec "bash -c 'rm -rf $APP_DIR && mkdir -p /srv && tar xzf /tmp/$TARNAME -C /srv && rm /tmp/$TARNAME'" fi rm -f "$TARBALL" elif [[ -n "$REPO_URL" ]]; then echo "Cloning repo..." pct_exec "bash -c 'if [ -d $APP_DIR/.git ]; then (cd $APP_DIR && git fetch && git reset --hard origin/HEAD); else git clone --depth 1 $REPO_URL $APP_DIR; fi'" fi if [[ -n "$ENV_FILE" && -f "$ENV_FILE" ]]; then if [[ -n "$PROXMOX_HOST" ]]; then REMOTE_ENV="/tmp/dapp-deploy-$$.env" echo "Copying .env to Proxmox host and pushing into container..." scp $SSH_OPTS "$ENV_FILE" root@"$PROXMOX_HOST":"$REMOTE_ENV" && \ run_pct push "$VMID" "$REMOTE_ENV" "$APP_DIR/.env" 2>/dev/null || true run_cmd "rm -f $REMOTE_ENV" 2>/dev/null || true else run_pct push "$VMID" "$ENV_FILE" "$APP_DIR/.env" 2>/dev/null || true fi fi echo "Building frontend-dapp..." pct_exec "bash -c 'cd $APP_DIR/frontend-dapp && (test -f package-lock.json && npm ci || npm install) && npm run build'" echo "Configuring nginx to serve dist..." pct_exec "bash -c 'cat > /etc/nginx/sites-available/dapp <<\"NGINXEOF\" server { listen 80 default_server; listen [::]:80 default_server; root /srv/smom-dbis-138/frontend-dapp/dist; index index.html; server_name _; include /srv/smom-dbis-138/frontend-dapp/nginx-dapp-snippet.conf; location / { try_files \$uri \$uri/ /index.html; } } NGINXEOF rm -f /etc/nginx/sites-enabled/default && ln -sf /etc/nginx/sites-available/dapp /etc/nginx/sites-enabled/dapp && nginx -t && systemctl reload nginx'" echo "Done. DApp LXC $VMID ($HOSTNAME) is serving at http://$IP" echo "Add NPMplus proxy host (e.g. dapp.d-bis.org) pointing to $IP:80. See docs/03-deployment/DAPP_LXC_DEPLOYMENT.md"