#!/usr/bin/env bash # 知命阁 Docker 部署脚本 # 用法:cd /opt/zhimingge && bash scripts/docker-deploy.sh set -euo pipefail APP_DIR="/opt/zhimingge" APP_PORT="${PORT:-3130}" cd "$APP_DIR" if [[ ! -f .env.local ]]; then echo "ERROR: 缺少 .env.local,请先:cp .env.example .env.local && nano .env.local" exit 1 fi mkdir -p data/history echo "==> 当前 commit: $(git rev-parse --short HEAD)" echo "==> 拉取最新代码..." git pull origin main echo "==> 更新后 commit: $(git rev-parse --short HEAD)" echo "==> 停止旧 PM2 进程(若存在,避免占用 ${APP_PORT})..." pm2 stop zhimingge 2>/dev/null || true pm2 delete zhimingge 2>/dev/null || true 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 --force-recreate echo "==> 状态" docker compose ps 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" echo "" echo "==> 可选:清理无用镜像释放磁盘" echo " bash scripts/docker-prune.sh"