diff --git a/Dockerfile b/Dockerfile index 7356ee4..0df6609 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,6 +27,7 @@ RUN addgroup --system --gid 1001 nodejs \ # standalone 产物 COPY --from=builder /app/.next/standalone ./ COPY --from=builder /app/.next/static ./.next/static +COPY --from=builder /app/public ./public # 卦辞 Markdown(运行时读取) COPY --from=builder /app/content ./content diff --git a/app/api/health/route.ts b/app/api/health/route.ts new file mode 100644 index 0000000..e6d6008 --- /dev/null +++ b/app/api/health/route.ts @@ -0,0 +1,8 @@ +export async function GET() { + return Response.json({ + ok: true, + service: "zhimingge", + apiAi: true, + build: "dba0245+", + }); +} diff --git a/docker-compose.yml b/docker-compose.yml index f73dd5c..07db3e0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,3 +14,13 @@ services: NODE_ENV: production PORT: "3130" HOSTNAME: "0.0.0.0" + healthcheck: + test: + [ + "CMD-SHELL", + "node -e \"fetch('http://127.0.0.1:3130/api/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\"", + ] + interval: 30s + timeout: 5s + retries: 3 + start_period: 15s diff --git a/scripts/docker-deploy.sh b/scripts/docker-deploy.sh index 3d3eee8..91bc6b8 100644 --- a/scripts/docker-deploy.sh +++ b/scripts/docker-deploy.sh @@ -14,22 +14,43 @@ if [[ ! -f .env.local ]]; then exit 1 fi +echo "==> 当前 commit: $(git rev-parse --short HEAD)" echo "==> 拉取最新代码..." git pull origin main +echo "==> 更新后 commit: $(git rev-parse --short HEAD)" -echo "==> 停止旧 PM2 进程(若存在)..." +echo "==> 停止旧 PM2 进程(若存在,避免占用 ${APP_PORT})..." pm2 stop zhimingge 2>/dev/null || true pm2 delete zhimingge 2>/dev/null || true -echo "==> 构建 Docker 镜像..." -docker compose build +if command -v fuser >/dev/null 2>&1; then + fuser -k "${APP_PORT}/tcp" 2>/dev/null || true +fi + +echo "==> 构建 Docker 镜像(无缓存)..." +docker compose build --no-cache echo "==> 启动容器..." -docker compose up -d +docker compose up -d --force-recreate echo "==> 状态" docker compose ps -sleep 2 -curl -s -o /dev/null -w "HTTP %{http_code}\n" "http://127.0.0.1:${APP_PORT}" || true + +echo "==> 等待服务就绪..." +for i in $(seq 1 30); do + if curl -sf "http://127.0.0.1:${APP_PORT}/api/health" >/dev/null 2>&1; then + echo "OK /api/health" + curl -s "http://127.0.0.1:${APP_PORT}/api/health" + echo "" + break + fi + if [[ "$i" -eq 30 ]]; then + echo "ERROR: /api/health 未响应,请检查:docker compose logs zhimingge" + exit 1 + fi + sleep 1 +done + +curl -s -o /dev/null -w "首页 HTTP %{http_code}\n" "http://127.0.0.1:${APP_PORT}/" || true echo "==> 部署完成。日志:docker compose logs -f zhimingge"