feat(07-02): Add CI/CD deployment scripts
- scripts/deploy.sh: Full deploy flow with fresh builds (--no-cache) - scripts/build-check.sh: Pre-flight staleness check - Docker labels for build tracking (git commit + timestamp) - Prevents stale container bug from recurring
This commit is contained in:
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
# Compare deployed container versions against local git HEAD
|
||||
# Warns if containers are stale (built from an older commit)
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
cd "$REPO_DIR"
|
||||
|
||||
LOCAL_COMMIT=$(git rev-parse HEAD)
|
||||
echo "Local HEAD: $(git rev-parse --short HEAD) ($LOCAL_COMMIT)"
|
||||
echo ""
|
||||
|
||||
check() {
|
||||
local name="$1"
|
||||
|
||||
if ! docker inspect "$name" &>/dev/null; then
|
||||
echo "[$name] Not running"
|
||||
return
|
||||
fi
|
||||
|
||||
local commit date
|
||||
commit=$(docker inspect "$name" --format '{{index .Config.Labels "org.opencontainers.image.revision"}}' 2>/dev/null)
|
||||
date=$(docker inspect "$name" --format '{{index .Config.Labels "org.opencontainers.image.created"}}' 2>/dev/null)
|
||||
|
||||
if [ -z "$commit" ] || [ "$commit" = "unknown" ]; then
|
||||
echo "[$name] WARNING: no build label found — redeploy with scripts/deploy.sh to add tracking"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "[$name] Built: ${commit:0:7} on ${date:-unknown}"
|
||||
|
||||
if [ "$commit" = "$LOCAL_COMMIT" ]; then
|
||||
echo "[$name] OK: up to date"
|
||||
else
|
||||
echo "[$name] STALE: container is behind local code — run scripts/deploy.sh"
|
||||
fi
|
||||
}
|
||||
|
||||
check "gravl-backend"
|
||||
check "gravl-frontend"
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
# Gravl deployment script
|
||||
# Prevents stale containers by always building fresh with --no-cache
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
LOG_FILE="$REPO_DIR/logs/deploy.log"
|
||||
BACKEND_HEALTH="http://localhost:3001/api/health"
|
||||
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
mkdir -p "$REPO_DIR/logs"
|
||||
cd "$REPO_DIR"
|
||||
|
||||
log "=== Deploy started ==="
|
||||
|
||||
# Pull latest code
|
||||
log "Pulling latest code..."
|
||||
git pull
|
||||
|
||||
# Capture build metadata
|
||||
GIT_COMMIT=$(git rev-parse HEAD)
|
||||
BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
log "Commit: $(git rev-parse --short HEAD) | Date: $BUILD_DATE"
|
||||
|
||||
# Build fresh images — no-cache prevents stale assets
|
||||
log "Building images (--no-cache)..."
|
||||
export GIT_COMMIT BUILD_DATE
|
||||
docker compose build --no-cache
|
||||
|
||||
# Restart containers with new images
|
||||
log "Starting containers..."
|
||||
docker compose up -d --force-recreate
|
||||
|
||||
# Health check: wait up to 60s for backend
|
||||
log "Health check..."
|
||||
for i in $(seq 1 12); do
|
||||
if curl -sf "$BACKEND_HEALTH" >/dev/null 2>&1; then
|
||||
log "Backend healthy"
|
||||
break
|
||||
fi
|
||||
[ "$i" -eq 12 ] && { log "ERROR: Health check failed after 60s"; exit 1; }
|
||||
log "Waiting... ($i/12)"
|
||||
sleep 5
|
||||
done
|
||||
|
||||
log "=== Deploy complete: ${GIT_COMMIT:0:7} ==="
|
||||
Reference in New Issue
Block a user