#!/bin/bash # deploy.sh - Deploy CA Lab Studio to its own stack on the VPS. # # This stack is independent of gnommoweb. It joins the shared `gnommo` external # network (owned by gu_common) so it can reach gnommo-db and be reached by the # shared nginx. # # Prerequisites on the server: # - gu_common stack is running (provides gnommo-db, nginx, and the gnommo network) # - ${REMOTE_DIR}/.env.prod exists with POSTGRES_USER, POSTGRES_PASSWORD # # Usage: # ./deploy.sh set -e SERVER="${DEPLOY_SERVER:-root@76.13.144.52}" REMOTE_DIR="${DEPLOY_DIR:-/opt/glitch_automata_lab}" COMPOSE="docker compose -f ${REMOTE_DIR}/docker-compose.prod.yml --env-file ${REMOTE_DIR}/.env.prod" # Refuse to run on the production server itself. TARGET_HOST=$(echo ${SERVER} | sed 's/.*@//') OWN_IP=$(curl -sf --max-time 3 ifconfig.me 2>/dev/null || echo "unknown") if [ "$OWN_IP" = "$TARGET_HOST" ]; then echo "Error: deploy.sh must be run from your local machine, not the server." exit 1 fi REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" echo "==> Deploying CA Lab Studio to ${SERVER}:${REMOTE_DIR}" # Ensure shared cross-project network exists. echo "==> Ensuring gnommo network exists..." ssh ${SERVER} "docker network create gnommo 2>/dev/null || true" # Ensure the remote dir exists. ssh ${SERVER} "mkdir -p ${REMOTE_DIR}" # Sync source files. .env.prod is never overwritten by deploy. echo "==> Syncing source..." rsync -avz --delete \ --exclude 'node_modules' \ --exclude '.git' \ --exclude 'dist' \ --exclude 'dist-standalone' \ --exclude '.DS_Store' \ --exclude '*.log' \ --exclude '.env' \ --exclude '.env.local' \ --exclude '.env.prod' \ ./ ${SERVER}:${REMOTE_DIR}/ # Sanity check: .env.prod must exist on the server. if ! ssh ${SERVER} "test -f ${REMOTE_DIR}/.env.prod"; then echo "Error: ${REMOTE_DIR}/.env.prod not found on server." echo " Create it with POSTGRES_USER, POSTGRES_PASSWORD (matching gu_common)," echo " and optionally LAB_DB (defaults to ca_studio)." exit 1 fi # Rebuild the lab image. CACHEBUST keeps the Docker layer cache honest when # only source files change. echo "==> Building lab image..." ssh ${SERVER} "CACHEBUST=\$(date +%s) && $COMPOSE build --build-arg CACHEBUST=\$CACHEBUST" # Start lab-db-init (idempotent — creates ca_studio + pgcrypto if missing), # then bring up the lab service. depends_on handles ordering. echo "==> Starting services..." ssh ${SERVER} "$COMPOSE up -d" # Wait for the lab to respond. It runs migrations on startup, so first # request may take a few seconds. echo "==> Waiting for lab to be ready..." for i in $(seq 1 24); do if ssh ${SERVER} "$COMPOSE exec -T lab node -e 'process.exit(0)'" 2>/dev/null; then echo " Lab is up." break fi echo " Not ready yet, waiting... ($i/24)" sleep 5 if [ $i -eq 24 ]; then echo "ERROR: Lab did not start within 2 minutes." echo " Check logs: ssh ${SERVER} '$COMPOSE logs --tail=100 lab'" exit 1 fi done echo "==> Done! Lab should be live at https://lab.glitch.university shortly."