#!/usr/bin/env bash set -Eeuo pipefail # Incremental deployment for an existing Dockerized AlphaX server. # # Required: # DEPLOY_HOST="user@server" # REMOTE_DIR="/path/to/existing/alphax-docker" # # Optional: # DEPLOY_BRANCH="main" # DEPLOY_MESSAGE="deploy: update alphax" # DEPLOY_REMOTE="origin" # DEPLOY_SERVICES="alphax-web alphax-scheduler alphax-price-streamer" # DEPLOY_RUN_MIGRATIONS=1 # DEPLOY_HEALTHCHECK_URL="http://127.0.0.1:8191/api/stats" # DEPLOY_SKIP_COMMIT=1 # DEPLOY_SKIP_PUSH=1 # DEPLOY_SKIP_BUILD=1 ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" DEPLOY_HOST="${DEPLOY_HOST:-}" REMOTE_DIR="${REMOTE_DIR:-}" DEPLOY_BRANCH="${DEPLOY_BRANCH:-main}" DEPLOY_REMOTE="${DEPLOY_REMOTE:-origin}" DEPLOY_MESSAGE="${DEPLOY_MESSAGE:-}" DEPLOY_SERVICES="${DEPLOY_SERVICES:-alphax-web alphax-scheduler alphax-price-streamer}" DEPLOY_RUN_MIGRATIONS="${DEPLOY_RUN_MIGRATIONS:-1}" DEPLOY_HEALTHCHECK_URL="${DEPLOY_HEALTHCHECK_URL:-http://127.0.0.1:8191/api/stats}" DEPLOY_SKIP_COMMIT="${DEPLOY_SKIP_COMMIT:-0}" DEPLOY_SKIP_PUSH="${DEPLOY_SKIP_PUSH:-0}" DEPLOY_SKIP_BUILD="${DEPLOY_SKIP_BUILD:-0}" die() { echo "[deploy] ERROR: $*" >&2 exit 1 } info() { echo "[deploy] $*" } require_cmd() { command -v "$1" >/dev/null 2>&1 || die "missing required command: $1" } quote_remote() { printf "%q" "$1" } if [[ -z "$DEPLOY_HOST" || -z "$REMOTE_DIR" ]]; then cat >&2 <<'USAGE' Usage: DEPLOY_HOST="user@server" REMOTE_DIR="/path/to/alphax-docker" DEPLOY_MESSAGE="deploy: xxx" bash scripts/deploy_server.sh What it does on the existing server directory: git fetch + git pull --ff-only docker compose build docker compose up -d postgres alphax-web alphax-scheduler alphax-price-streamer Useful options: DEPLOY_BRANCH=main DEPLOY_SERVICES="alphax-web alphax-scheduler alphax-price-streamer" DEPLOY_RUN_MIGRATIONS=1 DEPLOY_SKIP_COMMIT=1 DEPLOY_SKIP_PUSH=1 USAGE exit 2 fi require_cmd git require_cmd ssh cd "$ROOT_DIR" current_branch="$(git branch --show-current)" if [[ "$current_branch" != "$DEPLOY_BRANCH" ]]; then die "current branch is '$current_branch', expected '$DEPLOY_BRANCH'. Set DEPLOY_BRANCH or switch branch first." fi if [[ -n "$(git status --porcelain)" ]]; then if [[ "$DEPLOY_SKIP_COMMIT" == "1" ]]; then die "working tree has changes, but DEPLOY_SKIP_COMMIT=1. Commit or stash first." fi if [[ -z "$DEPLOY_MESSAGE" ]]; then die "working tree has changes. Provide DEPLOY_MESSAGE='deploy: ...' to commit them." fi info "staging local changes" git add -A info "creating local commit" git commit -m "$DEPLOY_MESSAGE" else info "working tree clean; no local commit needed" fi if [[ "$DEPLOY_SKIP_PUSH" != "1" ]]; then info "pushing $DEPLOY_REMOTE/$DEPLOY_BRANCH" git push "$DEPLOY_REMOTE" "$DEPLOY_BRANCH" else info "skip git push" fi remote_dir_q="$(quote_remote "$REMOTE_DIR")" branch_q="$(quote_remote "$DEPLOY_BRANCH")" remote_q="$(quote_remote "$DEPLOY_REMOTE")" services_q="$DEPLOY_SERVICES" health_q="$(quote_remote "$DEPLOY_HEALTHCHECK_URL")" remote_cmd=" set -Eeuo pipefail cd $remote_dir_q test -d .git || { echo '[deploy:remote] ERROR: REMOTE_DIR is not an existing git checkout'; exit 1; } test -f docker-compose.yml || { echo '[deploy:remote] ERROR: docker-compose.yml not found in REMOTE_DIR'; exit 1; } echo '[deploy:remote] fetching code' git fetch $remote_q $branch_q echo '[deploy:remote] checking out and pulling branch' git checkout $branch_q git pull --ff-only $remote_q $branch_q echo '[deploy:remote] docker compose config check' docker compose config >/dev/null if [[ '$DEPLOY_SKIP_BUILD' != '1' ]]; then echo '[deploy:remote] docker compose build' docker compose build $services_q else echo '[deploy:remote] skip docker build' fi if [[ '$DEPLOY_RUN_MIGRATIONS' == '1' ]]; then echo '[deploy:remote] running PostgreSQL migrations' docker compose run --rm alphax-web python scripts/postgres/run_migrations.py fi echo '[deploy:remote] docker compose up' docker compose up -d postgres $services_q echo '[deploy:remote] service status' docker compose ps if [[ -n $health_q ]]; then echo '[deploy:remote] healthcheck' curl -fsS $health_q >/dev/null fi " info "deploying on $DEPLOY_HOST:$REMOTE_DIR" ssh "$DEPLOY_HOST" "$remote_cmd" info "deployment complete"