#!/bin/sh set -eu app_dir="/srv/ai-chatbot" compose_dir="/srv/ai-chatbot-deploy" candidate_dir="$(mktemp -d "${app_dir}/.next-candidate.XXXXXX")" previous_dir="${app_dir}/.next-previous-$(date +%Y%m%dT%H%M%S)" build_container="ai-chatbot-build-$(date +%s)" if grep -Eq '^[[:space:]]*CANVAS_E2E_LOCAL[[:space:]]*=[[:space:]]*"?true"?[[:space:]]*$' "${app_dir}/.env.local"; then echo "Refusing production deployment while CANVAS_E2E_LOCAL=true." >&2 exit 1 fi cleanup_candidate() { if [ -d "$candidate_dir" ]; then rm -rf -- "$candidate_dir" fi } trap cleanup_candidate EXIT INT TERM docker run --rm \ --name "$build_container" \ --network host \ -e NODE_OPTIONS=--max-old-space-size=6144 \ -v "${app_dir}:/workspace" \ -v "${candidate_dir}:/workspace/.next" \ -w /workspace \ node:20.20.0-bookworm-slim \ sh -lc 'corepack enable && pnpm build' test -s "${candidate_dir}/BUILD_ID" docker stop ai-chatbot-app >/dev/null docker rm ai-chatbot-app >/dev/null if [ -d "${app_dir}/.next" ]; then mv "${app_dir}/.next" "$previous_dir" fi mv "$candidate_dir" "${app_dir}/.next" candidate_dir="" docker compose -f "${compose_dir}/docker-compose.yml" up -d app health_ok=false attempt=1 while [ "$attempt" -le 15 ]; do if curl -fsS --max-time 10 http://127.0.0.1:3125/login >/dev/null; then health_ok=true break fi sleep 2 attempt=$((attempt + 1)) done if [ "$health_ok" != true ]; then docker stop ai-chatbot-app >/dev/null 2>&1 || true docker rm ai-chatbot-app >/dev/null 2>&1 || true failed_dir="${app_dir}/.next-failed-$(date +%Y%m%dT%H%M%S)" mv "${app_dir}/.next" "$failed_dir" if [ -d "$previous_dir" ]; then mv "$previous_dir" "${app_dir}/.next" docker compose -f "${compose_dir}/docker-compose.yml" up -d app fi echo "Deployment health check failed; previous build restored." >&2 exit 1 fi echo "Production build activated. Previous build: ${previous_dir}"