Files
2026-10-18 08:55:43 +08:00

69 lines
2.6 KiB
Bash

#!/usr/bin/env bash
# ------------------------------------------------------------------
# fnOS 一键更新部署
#
# 用法(在 NAS 宿主机):
# bash /vol1/1000/Docker/idcard-api/deploy.sh
#
# 逻辑:增量构建(只重跑失效层,通常 10-30s)→ 等就绪 → 校验镜像内代码
# 是否真的更新了 → 打印 health。校验失败自动降级为 --no-cache 全量重建。
# ------------------------------------------------------------------
set -uo pipefail
# 切到脚本所在目录,避免路径写死
cd "$(dirname "$0")" || exit 1
PROJECT_NAME="icd" # compose 项目名(镜像名 icd-idcard-api 的前缀)
SERVICE="idcard-api" # container_name
PORT=8000
MARKER="auth_enabled" # 用它能判断镜像里是新代码
echo "==> 目录: $(pwd)"
# ---------- 1. 增量构建 + 启动 ----------
echo "==> 1/4 构建并启动(增量,通常 10-30 秒)"
if ! sudo docker compose -p "$PROJECT_NAME" up -d --build; then
echo "!! 构建失败。常见原因:基础镜像源 401,检查 Dockerfile 的 BASE_IMAGE"
exit 1
fi
# ---------- 2. 等服务就绪 ----------
echo "==> 2/4 等待服务就绪"
ready=0
for _ in $(seq 1 30); do
if curl -sf "http://127.0.0.1:$PORT/api/v1/idcard/health" >/dev/null 2>&1; then
ready=1
break
fi
sleep 2
done
if [ "$ready" -ne 1 ]; then
echo "!! 服务 60 秒内未就绪,看日志:sudo docker logs --tail 50 $SERVICE"
exit 1
fi
# ---------- 3. 校验镜像内代码是否真的更新 ----------
echo "==> 3/4 校验容器内代码版本"
count=$(sudo docker exec "$SERVICE" grep -c "$MARKER" /app/app/main.py 2>/dev/null || echo 0)
if [ "${count:-0}" -lt 1 ]; then
echo "!! 容器内仍是旧代码,降级为 --no-cache 全量重建(需要几分钟)"
sudo docker compose -p "$PROJECT_NAME" build --no-cache || exit 1
sudo docker compose -p "$PROJECT_NAME" up -d --force-recreate || exit 1
count=$(sudo docker exec "$SERVICE" grep -c "$MARKER" /app/app/main.py 2>/dev/null || echo 0)
if [ "${count:-0}" -lt 1 ]; then
echo "!! 全量重建后代码仍是旧的。检查 compose 项目目录是否就是本目录:"
sudo docker inspect "$SERVICE" --format '{{index .Config.Labels "com.docker.compose.project.working_dir"}}'
exit 1
fi
fi
echo " 容器内代码已更新(匹配 $count 处)"
# ---------- 4. 健康检查 ----------
echo "==> 4/4 健康检查"
curl -s "http://127.0.0.1:$PORT/api/v1/idcard/health"
echo
echo
echo "部署完成。"
echo " 看日志:sudo docker logs -f $SERVICE"
echo " 看内存:sudo docker stats --no-stream $SERVICE"