Files
butubb c1068845a9
Deploy VitePress site to Pages / build (push) Canceled after 0s
Deploy VitePress site to Pages / Deploy (push) Canceled after 0s
fix(deploy): 部署时必须强制重建容器
代码是 bind mount,容器配置与镜像都没变,所以裸的 `docker compose up -d` 会判定无需变更直接跳过,改了 .py 也不会生效。前端产物是磁盘上的静态文件、能即时生效,这一点很容易把问题盖住,直到有人改了后端代码才发现。

首次实测即命中:跑 deploy.sh 的输出是 'Container mediacrawler Running',没有重启。
2026-10-07 15:22:00 +08:00

64 lines
2.3 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
#
# 更新这台机器上的部署。用法:
#
# ./deploy.sh
#
# 为什么需要脚本而不是一句 `git pull && docker compose up -d`:
# 前端产物 api/webui 是 gitignore 的(它由 vite 生成),git pull 带不过来。
# 所以代码更新之后必须在服务器上重建一次前端,否则页面还是旧的。
# 这一步在容器里做,好处是服务器不需要装 Node —— 只有 Docker。
#
# node_modules 和 npm 缓存都留在挂载目录内,重复构建不会重新下载。
set -euo pipefail
cd "$(dirname "$0")"
# 用镜像里的解释器跑,宿主机的 Python 版本无关。
IMAGE=mediacrawler:latest
before=$(git rev-parse HEAD)
git pull --ff-only
after=$(git rev-parse HEAD)
if [ "$before" = "$after" ]; then
echo "== 代码已是最新($after)"
else
echo "== 代码更新 $before -> $after"
git --no-pager log --oneline "$before..$after" | sed 's/^/ /'
fi
# 前端重建的两种情况:产物根本不存在(首次部署),或 webui/ 有改动。
if [ ! -f api/webui/index.html ]; then
need_build=1
reason="前端产物不存在"
elif [ "$before" != "$after" ] && ! git diff --quiet "$before" "$after" -- webui/; then
need_build=1
reason="webui/ 有改动"
else
need_build=0
reason=""
fi
if [ "$need_build" = "1" ]; then
echo "== 重建前端($reason)"
# -u 1000:1000 而不是 root:这里产出的文件要留在这个目录里给后面用,
# 以 root 生成的 node_modules 会让下次构建和人工清理都变得别扭。
# HOME 指向挂载目录,这样 npm 的缓存在宿主机上,重建时能复用。
docker run --rm \
-u 1000:1000 \
-w /app/webui \
-v "$PWD:/app" \
-e HOME=/app/webui \
-e npm_config_registry=https://registry.npmmirror.com \
"$IMAGE" sh -c 'npm ci --no-audit --no-fund && npm run build'
else
echo "== 前端无改动,跳过构建"
fi
# --force-recreate,而不是裸的 `up -d`:代码是 bind mount,容器配置和镜像都没变,
# 所以 `up -d` 会判定"无需变更"直接跳过,Python 代码的改动根本不会生效。前端产物是
# 磁盘上的静态文件,能即时生效,这一点很容易掩盖上面那个问题,直到有人改了 .py 才发现。
echo "== 重启容器"
docker compose up -d --force-recreate
docker compose ps