76 lines
2.6 KiB
Bash
76 lines
2.6 KiB
Bash
#! /bin/bash
|
|
set -euo pipefail
|
|
|
|
# Usage: ./scripts/rebuild-prod.sh [branch]
|
|
# Default branch is current; pass a branch to checkout before pulling/building.
|
|
|
|
COMPOSE_FILE=docker-compose-prod.yml
|
|
|
|
echo "[1/7] Git: Fetch & pull latest changes"
|
|
if [ "${1-}" != "" ]; then
|
|
git fetch origin "$1"
|
|
git checkout "$1"
|
|
fi
|
|
git pull --rebase
|
|
|
|
echo "[2/7] Stop and remove running services (including orphans)"
|
|
sudo docker compose -f "$COMPOSE_FILE" down --remove-orphans || true
|
|
|
|
echo "[3/7] Pull base images (e.g., caddy)"
|
|
sudo docker compose -f "$COMPOSE_FILE" pull || true
|
|
|
|
echo "[4/7] Build application image without cache"
|
|
# Falls docker-compose-prod.yml den target 'production-prebuilt' nutzt, vorher lokal bauen
|
|
if grep -q "target:\s*production-prebuilt" "$COMPOSE_FILE" 2>/dev/null; then
|
|
echo "Detected target production-prebuilt in $COMPOSE_FILE - building locally first..."
|
|
pnpm install --frozen-lockfile --prod || exit 1
|
|
pnpm run build || exit 1
|
|
fi
|
|
|
|
sudo docker compose -f "$COMPOSE_FILE" build --no-cache
|
|
echo "Build completed successfully. Native modules compiled for Alpine Linux."
|
|
|
|
echo "[5/7] Start services in background"
|
|
sudo docker compose -f "$COMPOSE_FILE" up -d
|
|
|
|
echo "[6/7] Wait for app healthcheck to pass"
|
|
# Wait up to ~90s for healthy status using docker inspect (no jq dependency)
|
|
for i in {1..18}; do
|
|
# Check health status if available
|
|
HEALTH=$(sudo docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{end}}' stargirlnails-app 2>/dev/null || true)
|
|
if [ "$HEALTH" = "healthy" ]; then
|
|
echo "Service is healthy."
|
|
break
|
|
fi
|
|
|
|
# Fallback: ensure container is running
|
|
STATE=$(sudo docker inspect -f '{{.State.Status}}' stargirlnails-app 2>/dev/null || true)
|
|
if [ "$STATE" = "running" ] && [ -z "$HEALTH" ]; then
|
|
echo "Service is running (no healthcheck reported)."
|
|
break
|
|
fi
|
|
|
|
sleep 5
|
|
done
|
|
|
|
echo "[6b/7] Verify HTTP /health via Caddy (localhost)"
|
|
for i in {1..12}; do
|
|
if curl -fsS http://localhost/health >/dev/null 2>&1; then
|
|
echo "Caddy proxy responds OK on /health."
|
|
break
|
|
fi
|
|
sleep 5
|
|
done
|
|
|
|
echo "[6c/7] Verifying bcrypt installation in production container..."
|
|
sudo docker compose -f "$COMPOSE_FILE" exec stargirlnails node -e "require('bcrypt')" && echo "✓ bcrypt OK" || echo "✗ bcrypt FAILED"
|
|
|
|
echo "[7/7] Tail recent logs for app and caddy (press Ctrl+C to exit)"
|
|
sudo docker compose -f "$COMPOSE_FILE" logs --since=10m -f stargirlnails &
|
|
APP_LOG_PID=$!
|
|
sudo docker compose -f "$COMPOSE_FILE" logs --since=10m -f caddy &
|
|
CADDY_LOG_PID=$!
|
|
|
|
trap "echo 'Stopping log tails...'; kill $APP_LOG_PID $CADDY_LOG_PID 2>/dev/null || true" INT TERM
|
|
wait $APP_LOG_PID $CADDY_LOG_PID || true
|