mirror of
https://github.com/mauricioabh/arbpulse.git
synced 2026-07-27 15:47:43 +00:00
f6108d8f8f
Build the Docker image in GitHub Actions, publish to ghcr.io/mauricioabh/arbpulse (latest + sha tags), then SSH into the Hetzner VPS to docker compose pull + up -d with a health-check gate. The VPS no longer builds images, keeping CPU/RAM free for the running apps and making rollbacks a matter of pulling a previous sha tag. - .github/workflows/vps-deploy.yml: build-push (GHCR) + deploy (SSH) jobs - deploy/docker-compose.yml: app image now ghcr.io/mauricioabh/arbpulse - deploy/deploy.sh: pulls from GHCR by default (BUILD=1 for local build), default APP_DIR aligned to /root/projects/arbpulse - docs: deploy/README.md CI/CD section + paths, README deploy section Co-authored-by: Cursor <cursoragent@cursor.com>
97 lines
3.2 KiB
Bash
Executable File
97 lines
3.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Idempotent VPS deploy for Arb Pulse (Ubuntu/Debian).
|
|
# Safe to re-run: installs Docker if missing, clones or fast-forwards the repo,
|
|
# pulls the CI-built image from GHCR (or builds locally with BUILD=1) and
|
|
# restarts the containers. On first run it creates .env from the example and
|
|
# stops so you can fill in DOMAIN + secrets.
|
|
#
|
|
# NOTE: normal production deploys are automatic — push/merge to `main` triggers
|
|
# .github/workflows/vps-deploy.yml (build in CI -> GHCR -> SSH pull + restart).
|
|
# This script is the manual/bootstrap path.
|
|
#
|
|
# Default: runs ONLY the app on 127.0.0.1:8080 (put it behind your host reverse
|
|
# proxy — see deploy/nginx/). Set WITH_CADDY=1 to also start the bundled Caddy on
|
|
# 80/443 (only for a fresh server with nothing else on those ports).
|
|
set -euo pipefail
|
|
|
|
REPO_URL="${REPO_URL:-https://github.com/mauricioabh/arbpulse.git}"
|
|
APP_DIR="${APP_DIR:-/root/projects/arbpulse}"
|
|
BRANCH="${BRANCH:-main}"
|
|
WITH_CADDY="${WITH_CADDY:-0}"
|
|
# BUILD=1 builds the image locally instead of pulling from GHCR (fallback).
|
|
BUILD="${BUILD:-0}"
|
|
|
|
echo "==> Arb Pulse VPS deploy (branch: $BRANCH, dir: $APP_DIR)"
|
|
|
|
# 1) Docker + compose plugin
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
echo "==> Installing Docker Engine..."
|
|
curl -fsSL https://get.docker.com | sh
|
|
fi
|
|
docker --version
|
|
if ! docker compose version >/dev/null 2>&1; then
|
|
echo "ERROR: 'docker compose' plugin not available. Install docker-compose-plugin." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# 2) Repo (clone or fast-forward)
|
|
if [ ! -d "$APP_DIR/.git" ]; then
|
|
echo "==> Cloning $REPO_URL into $APP_DIR"
|
|
sudo mkdir -p "$APP_DIR"
|
|
sudo chown "$(id -un)":"$(id -gn)" "$APP_DIR"
|
|
git clone --branch "$BRANCH" "$REPO_URL" "$APP_DIR"
|
|
else
|
|
echo "==> Updating existing repo in $APP_DIR"
|
|
git -C "$APP_DIR" fetch origin "$BRANCH"
|
|
git -C "$APP_DIR" checkout "$BRANCH"
|
|
git -C "$APP_DIR" pull --ff-only origin "$BRANCH"
|
|
fi
|
|
|
|
cd "$APP_DIR/deploy"
|
|
|
|
# 3) Environment file
|
|
if [ ! -f .env ]; then
|
|
cp .env.vps.example .env
|
|
echo
|
|
echo "==> Created $APP_DIR/deploy/.env from the example."
|
|
echo " Edit it now (set DOMAIN, and optionally SENTRY_DSN / UPSTASH_*),"
|
|
echo " then run this script again to build and start."
|
|
exit 0
|
|
fi
|
|
|
|
# 4) Image: pull from GHCR (default) or build locally (BUILD=1)
|
|
if [ "$BUILD" = "1" ]; then
|
|
echo "==> Building image locally..."
|
|
docker compose build app
|
|
else
|
|
echo "==> Pulling image from GHCR..."
|
|
docker compose pull app
|
|
fi
|
|
|
|
# 5) Run
|
|
if [ "$WITH_CADDY" = "1" ]; then
|
|
echo "==> Starting app + bundled Caddy (ports 80/443)..."
|
|
docker compose --profile caddy up -d
|
|
else
|
|
echo "==> Starting app only (127.0.0.1:8080)..."
|
|
docker compose up -d app
|
|
fi
|
|
|
|
echo "==> Waiting for health..."
|
|
sleep 8
|
|
docker compose ps
|
|
echo
|
|
if curl -fsS http://127.0.0.1:8080/api/health >/dev/null 2>&1; then
|
|
echo "==> App healthy on 127.0.0.1:8080."
|
|
else
|
|
echo "!! Health check not passing yet. Inspect: docker compose logs -f app"
|
|
fi
|
|
|
|
if [ "$WITH_CADDY" = "1" ]; then
|
|
echo "==> Bundled Caddy will issue HTTPS once DNS for \$DOMAIN points here."
|
|
echo "==> Verify: curl -s https://\$DOMAIN/api/health"
|
|
else
|
|
echo "==> App is bound to 127.0.0.1:8080. Put it behind your host reverse proxy:"
|
|
echo " see $APP_DIR/deploy/nginx/arbpulse.wayool.com.conf (nginx + certbot)."
|
|
fi
|