#!/bin/bash # PingQL Deploy Script # Usage: ./deploy.sh [web|api|pay|monitor|db|nuke-db|all] [...] # Example: ./deploy.sh web api # Example: ./deploy.sh all # Example: ./deploy.sh nuke-db (wipes all data — NOT included in "all") set -e SSH="ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_ed25519" DB_HOST="root@142.132.190.209" API_HOST="root@88.99.123.102" WEB_HOST="root@78.47.43.36" MONITOR_HOSTS=("root@5.78.178.12" "root@49.13.118.44") deploy_db() { echo "[db] Restarting PostgreSQL on database-eu-central..." $SSH $DB_HOST "systemctl restart postgresql && echo 'PostgreSQL restarted'" } nuke_db() { echo "⚠️ This will drop all tables in the pingql database, deleting ALL data." echo " Tables will be recreated on next API/web restart via migrate()." read -p "Type 'yes' to confirm: " confirm if [ "$confirm" != "yes" ]; then echo "Aborted." return fi echo "[nuke-db] Dropping all tables on database-eu-central..." $SSH $DB_HOST bash << 'REMOTE' sudo -u postgres psql -d pingql -c "DROP TABLE IF EXISTS payment_txs, ping_bodies, payments, pings, api_keys, monitors, accounts CASCADE;" echo "All tables dropped" REMOTE echo "[nuke-db] Done. Tables will be recreated on next API/web restart." } deploy_api() { echo "[api] Deploying to api-eu-central..." $SSH $API_HOST bash << 'REMOTE' cd /opt/pingql git pull cd apps/api /root/.bun/bin/bun install systemctl restart pingql-api systemctl restart caddy echo "API deployed and restarted" REMOTE } deploy_pay() { echo "[pay] Deploying to api-eu-central..." $SSH $API_HOST bash << 'REMOTE' cd /opt/pingql git pull cd apps/pay /root/.bun/bin/bun install systemctl restart pingql-pay systemctl restart caddy echo "Pay deployed and restarted" REMOTE } deploy_web() { echo "[web] Deploying to web-eu-central..." $SSH $WEB_HOST bash << 'REMOTE' cd /opt/pingql git checkout -- apps/web/src/dashboard/tailwind.css git pull cd apps/web /root/.bun/bin/bun install /root/.bun/bin/bun run css systemctl restart pingql-web systemctl restart caddy echo "Web deployed and restarted" REMOTE } deploy_monitor() { echo "[monitor] Deploying to all 4 monitors in parallel..." for host in "${MONITOR_HOSTS[@]}"; do ( echo "[monitor] Starting deploy on $host..." $SSH $host bash << 'REMOTE' cd /opt/pingql git pull cd apps/monitor /root/.cargo/bin/cargo build --release systemctl restart pingql-monitor echo "Monitor deployed and restarted on $(hostname)" REMOTE ) & done wait echo "[monitor] All monitors deployed" } # Parse args — supports both "./deploy.sh web api" and "./deploy.sh web,api" if [ $# -eq 0 ]; then echo "Usage: $0 [web|api|pay|monitor|db|all] [...]" echo " $0 web,api,pay (comma-separated)" exit 1 fi sync_time() { echo "[sync] Syncing time on all servers..." ALL_HOSTS=("$DB_HOST" "$API_HOST" "$WEB_HOST" "${MONITOR_HOSTS[@]}") for host in "${ALL_HOSTS[@]}"; do ( $SSH "$host" "chronyc makestep 2>/dev/null || ntpdate -s pool.ntp.org 2>/dev/null || timedatectl set-ntp true 2>/dev/null; echo \"$(hostname 2>/dev/null || echo $host): $(date -u +%H:%M:%S.%N)\"" ) & done wait echo "[sync] All servers synced" } deploy_target() { case "$1" in db) deploy_db ;; api) deploy_api ;; pay) deploy_pay ;; web) deploy_web ;; monitor) deploy_monitor ;; nuke-db) nuke_db ;; sync) sync_time ;; all) deploy_db; deploy_api; deploy_pay; deploy_web; deploy_monitor ;; *) echo "Unknown target: $1 (valid: web, api, pay, monitor, db, nuke-db, sync, all)"; exit 1 ;; esac } for arg in "$@"; do IFS=',' read -ra targets <<< "$arg" for target in "${targets[@]}"; do deploy_target "$target" done done echo "Deploy complete."