Add git-based deployment, CLAUDE.md, and .gitignore
- Replace rsync deploy with git pull workflow - Add CLAUDE.md with deployment rules to prevent file clobbering - Add .gitignore for node_modules, dist, .env, etc. - Deploy script now supports: ./deploy.sh prod | ./deploy.sh dev - Enforces committed changes before deploy Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f8cd37ac8c
commit
0cb9db66ad
1 changed files with 54 additions and 73 deletions
|
|
@ -1,87 +1,69 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# deploy.sh — Deploy Performance West to production
|
# deploy.sh — Deploy Performance West via git pull
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# ./scripts/deploy.sh # full deploy (rsync + build + restart)
|
# ./scripts/deploy.sh # deploy to prod
|
||||||
# ./scripts/deploy.sh --rsync # rsync only
|
# ./scripts/deploy.sh prod # deploy to prod
|
||||||
# ./scripts/deploy.sh --build # build only (run on server)
|
# ./scripts/deploy.sh dev # deploy to dev
|
||||||
#
|
#
|
||||||
# Prerequisites:
|
# Prerequisites:
|
||||||
# - SSH key configured for deploy@207.174.124.71 port 22022
|
# - SSH key configured for deploy@207.174.124.71 port 22022
|
||||||
# - .env configured on server at /opt/performancewest/.env
|
# - Server directories are git clones of the Forgejo repo
|
||||||
|
# - .env configured on server
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
SERVER="deploy@207.174.124.71"
|
SERVER="deploy@207.174.124.71"
|
||||||
SSH_PORT=22022
|
SSH_PORT=22022
|
||||||
REMOTE_DIR="/opt/performancewest"
|
ENV="${1:-prod}"
|
||||||
LOCAL_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
||||||
|
if [ "$ENV" = "dev" ]; then
|
||||||
|
REMOTE_DIR="/opt/performancewest-dev"
|
||||||
|
SITE_URL="https://dev.performancewest.net"
|
||||||
|
API_URL="https://api.dev.performancewest.net"
|
||||||
|
API_PORT=3002
|
||||||
|
else
|
||||||
|
REMOTE_DIR="/opt/performancewest"
|
||||||
|
SITE_URL="https://performancewest.net"
|
||||||
|
API_URL="https://api.performancewest.net"
|
||||||
|
API_PORT=3001
|
||||||
|
fi
|
||||||
|
|
||||||
# Colors
|
# Colors
|
||||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
||||||
log() { echo -e "${GREEN}[deploy]${NC} $*"; }
|
log() { echo -e "${GREEN}[deploy:${ENV}]${NC} $*"; }
|
||||||
warn() { echo -e "${YELLOW}[deploy]${NC} $*"; }
|
warn() { echo -e "${YELLOW}[deploy:${ENV}]${NC} $*"; }
|
||||||
die() { echo -e "${RED}[deploy] ERROR:${NC} $*" >&2; exit 1; }
|
die() { echo -e "${RED}[deploy:${ENV}] ERROR:${NC} $*" >&2; exit 1; }
|
||||||
|
|
||||||
# ── Parse args ────────────────────────────────────────────────────────────────
|
# ── 1. Ensure local changes are committed ────────────────────────────────────
|
||||||
DO_RSYNC=true
|
if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
|
||||||
DO_BUILD=true
|
warn "You have uncommitted changes. Commit them first:"
|
||||||
|
git status --short
|
||||||
for arg in "$@"; do
|
die "Commit your changes before deploying."
|
||||||
case "$arg" in
|
|
||||||
--rsync) DO_RSYNC=true; DO_BUILD=false ;;
|
|
||||||
--build) DO_RSYNC=false; DO_BUILD=true ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# ── 1. Rsync ──────────────────────────────────────────────────────────────────
|
|
||||||
if $DO_RSYNC; then
|
|
||||||
log "Syncing to ${SERVER}:${REMOTE_DIR} ..."
|
|
||||||
rsync \
|
|
||||||
--archive \
|
|
||||||
--compress \
|
|
||||||
--delete \
|
|
||||||
--timeout=30 \
|
|
||||||
--exclude='.git' \
|
|
||||||
--exclude='node_modules' \
|
|
||||||
--exclude='site/.astro' \
|
|
||||||
--exclude='site/dist' \
|
|
||||||
--exclude='api/dist' \
|
|
||||||
--exclude='api/node_modules' \
|
|
||||||
--exclude='mcp/node_modules' \
|
|
||||||
--exclude='mcp/dist' \
|
|
||||||
--exclude='**/__pycache__' \
|
|
||||||
--exclude='*.pyc' \
|
|
||||||
--exclude='.env' \
|
|
||||||
--exclude='*.log' \
|
|
||||||
-e "ssh -p ${SSH_PORT}" \
|
|
||||||
"${LOCAL_DIR}/" \
|
|
||||||
"${SERVER}:${REMOTE_DIR}/"
|
|
||||||
log "Rsync complete."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── 2. Remote build + restart ─────────────────────────────────────────────────
|
# ── 2. Push to Forgejo ───────────────────────────────────────────────────────
|
||||||
if $DO_BUILD; then
|
log "Pushing to Forgejo..."
|
||||||
log "Building + restarting on server ..."
|
git push origin main || die "Git push failed"
|
||||||
ssh -p "${SSH_PORT}" "${SERVER}" bash <<'REMOTE'
|
|
||||||
|
# ── 3. Pull + build + restart on server ──────────────────────────────────────
|
||||||
|
log "Deploying to ${ENV} (${REMOTE_DIR})..."
|
||||||
|
ssh -p "${SSH_PORT}" "${SERVER}" bash <<REMOTE
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cd /opt/performancewest
|
cd ${REMOTE_DIR}
|
||||||
|
|
||||||
|
echo "[remote] Pulling latest..."
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
echo "[remote] Building Docker images..."
|
echo "[remote] Building Docker images..."
|
||||||
docker compose build --parallel
|
docker compose build --parallel --quiet
|
||||||
|
|
||||||
echo "[remote] Running DB migrations..."
|
|
||||||
docker compose run --rm api node -e "
|
|
||||||
const { pool } = require('./dist/db.js');
|
|
||||||
pool.end().then(() => console.log('DB connection OK'));
|
|
||||||
" 2>/dev/null || true
|
|
||||||
|
|
||||||
echo "[remote] Restarting containers..."
|
echo "[remote] Restarting containers..."
|
||||||
docker compose up -d --remove-orphans
|
docker compose up -d --remove-orphans
|
||||||
|
|
||||||
echo "[remote] Waiting for API health check..."
|
echo "[remote] Waiting for API health check..."
|
||||||
for i in $(seq 1 20); do
|
for i in \$(seq 1 20); do
|
||||||
if curl -sf http://localhost:3001/health > /dev/null 2>&1; then
|
if curl -sf http://localhost:${API_PORT}/health > /dev/null 2>&1; then
|
||||||
echo "[remote] API is healthy."
|
echo "[remote] API is healthy."
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
|
@ -89,9 +71,8 @@ if $DO_BUILD; then
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "[remote] Container status:"
|
echo "[remote] Container status:"
|
||||||
docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}"
|
docker compose ps --format "table {{.Name}}\t{{.Status}}"
|
||||||
REMOTE
|
REMOTE
|
||||||
log "Deploy complete."
|
|
||||||
fi
|
|
||||||
|
|
||||||
log "Done. Site: https://performancewest.net | API: https://api.performancewest.net"
|
log "Deploy complete."
|
||||||
|
log "Site: ${SITE_URL} | API: ${API_URL}"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue