From 88dec71a41a49966623069ae35f8f30890e01c8f Mon Sep 17 00:00:00 2001 From: 134 Date: Thu, 20 Aug 2026 19:32:49 +0800 Subject: [PATCH] ops: make production builds atomic --- scripts/deploy-production-atomic.sh | 52 +++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100755 scripts/deploy-production-atomic.sh diff --git a/scripts/deploy-production-atomic.sh b/scripts/deploy-production-atomic.sh new file mode 100755 index 000000000..5b4dd4c17 --- /dev/null +++ b/scripts/deploy-production-atomic.sh @@ -0,0 +1,52 @@ +#!/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)" + +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 +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 + +if ! curl -fsS --retry 12 --retry-delay 2 --max-time 10 \ + http://127.0.0.1:3125/login >/dev/null; then + docker stop 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}"