90 lines
3.0 KiB
Bash
Executable File
90 lines
3.0 KiB
Bash
Executable File
#!/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."
|