🚀 添加从 master 部署生产脚本

This commit is contained in:
Orion
2026-06-05 08:57:09 +08:00
parent b930f68aa4
commit 1eaa82c525
2 changed files with 133 additions and 10 deletions
+21 -10
View File
@@ -22,22 +22,33 @@ deploy-filecodebox-test
COPY_PROD_DATA=1 deploy-filecodebox-test
```
## 生产环境官方重建
## 生产环境从 master 部署
生产环境默认保持官方镜像,不直接部署测试分支代码
生产环境应该指向你的 Gitea 仓库 `master` 分支,而不是测试分支,也不是直接手改容器
如果只是让生产回到/更新官方镜像,执行:
执行:
```bash
CONFIRM=YES deploy-filecodebox-prod-master
```
脚本行为:
- 拉取 `http://127.0.0.1:3000/orion/filecodebox.git``master``/opt/src/filecodebox-production`
- 使用该 `master` 工作树构建生产镜像 `local/filecodebox:master`
- 保持 1Panel 生产目录和数据卷不变:`/opt/1panel/apps/filecodebox/filecodebox/data:/app/data`
- 重建/重启生产容器 `filecodebox`
- 验证生产首页不包含 `fcb-analytics.js` 测试脚本。
## 生产官方镜像回滚
如果以后需要临时回滚到上游官方 Docker Hub 镜像:
```bash
CONFIRM=YES deploy-filecodebox-prod-official
```
脚本行为:
- 备份生产 `docker-compose.yml``data/filecodebox.db`
- 确认生产 Compose 使用 `lanol/filecodebox:beta`
- 重建/重启生产容器。
- 验证生产首页不包含 `fcb-analytics.js` 测试脚本。
这个只作为兜底回滚,不是正常生产发布流程。
## 推荐流程
@@ -46,4 +57,4 @@ CONFIRM=YES deploy-filecodebox-prod-official
3. 在测试页面确认没问题。
4. 提交测试分支。
5. 通过 PR/合并进入 `master`
6. 生产仍使用官方镜像;除非明确决定发布自定义生产镜像,否则只执行官方重建脚本
6. 执行 `CONFIRM=YES deploy-filecodebox-prod-master` 发布生产
+112
View File
@@ -0,0 +1,112 @@
#!/usr/bin/env bash
set -euo pipefail
REPO_URL="${REPO_URL:-http://127.0.0.1:3000/orion/filecodebox.git}"
TOKEN_FILE="${TOKEN_FILE:-/root/.cache/gitea-filecodebox-token}"
PROD_REPO_DIR="${PROD_REPO_DIR:-/opt/src/filecodebox-production}"
PROD_DIR="${PROD_DIR:-/opt/1panel/apps/filecodebox/filecodebox}"
BRANCH="${BRANCH:-master}"
IMAGE="${IMAGE:-local/filecodebox:master}"
PORT="${PORT:-40157}"
CONFIRM="${CONFIRM:-}"
log() { printf '\033[1;32m[deploy-prod-master]\033[0m %s\n' "$*"; }
err() { printf '\033[1;31m[deploy-prod-master]\033[0m %s\n' "$*" >&2; }
command -v git >/dev/null 2>&1 || { err "missing command: git"; exit 1; }
command -v docker >/dev/null 2>&1 || { err "missing command: docker"; exit 1; }
command -v curl >/dev/null 2>&1 || { err "missing command: curl"; exit 1; }
if [[ "$CONFIRM" != "YES" ]]; then
cat >&2 <<EOF
这是生产环境脚本:从你的 Gitea 仓库 $BRANCH 分支构建并部署生产镜像。
生产数据目录保持不变:$PROD_DIR/data -> /app/data
如确认执行,请使用:
CONFIRM=YES deploy-filecodebox-prod-master
EOF
exit 2
fi
log "prepare production source: $REPO_URL#$BRANCH"
AUTH_REPO_URL="$REPO_URL"
if [[ -f "$TOKEN_FILE" && "$REPO_URL" == http://127.0.0.1:3000/* ]]; then
TOKEN="$(tr -d '\n' < "$TOKEN_FILE")"
AUTH_REPO_URL="http://orion:${TOKEN}@127.0.0.1:3000/orion/filecodebox.git"
fi
if [[ ! -d "$PROD_REPO_DIR/.git" ]]; then
rm -rf "$PROD_REPO_DIR"
git clone "$AUTH_REPO_URL" "$PROD_REPO_DIR"
fi
cd "$PROD_REPO_DIR"
git remote set-url origin "$AUTH_REPO_URL"
git fetch origin "$BRANCH"
git checkout -B "$BRANCH" "origin/$BRANCH"
git reset --hard "origin/$BRANCH"
commit="$(git rev-parse HEAD)"
log "production source commit: $commit"
cd "$PROD_DIR"
mkdir -p backups
TS="$(date +%Y%m%d%H%M%S)"
log "backup compose and database"
cp -a docker-compose.yml "backups/docker-compose.yml.before-prod-master.$TS"
if [[ -f data/filecodebox.db ]]; then
cp -a data/filecodebox.db "backups/filecodebox.db.before-prod-master.$TS"
fi
log "write production compose: build from $PROD_REPO_DIR"
python3 - <<PY
from pathlib import Path
p=Path('docker-compose.yml')
s=p.read_text()
lines=[]
skip_next_context=False
in_build=False
for line in s.splitlines():
stripped=line.strip()
if stripped.startswith('image:'):
indent=line[:len(line)-len(line.lstrip())]
lines.append(indent+'image: $IMAGE')
continue
if stripped == 'build:' or stripped.startswith('build:'):
continue
if stripped.startswith('context:'):
continue
lines.append(line)
text='\n'.join(lines)+'\n'
if 'image: $IMAGE' not in text:
raise SystemExit('failed to set production image')
needle=' image: $IMAGE\n'
replacement=' image: $IMAGE\n build:\n context: $PROD_REPO_DIR\n'
text=text.replace(needle, replacement)
p.write_text(text)
PY
docker compose config >/dev/null
log "build $IMAGE"
docker compose build filecodebox
log "recreate production container"
docker compose up -d --no-build filecodebox
log "wait for http://127.0.0.1:$PORT/"
for i in $(seq 1 45); do
if curl -fsS "http://127.0.0.1:$PORT/" >/tmp/filecodebox-prod-index.html; then
break
fi
sleep 1
if [[ "$i" == "45" ]]; then
err "production environment did not become ready"
docker logs --tail 100 filecodebox || true
exit 3
fi
done
if grep -q 'fcb-analytics.js' /tmp/filecodebox-prod-index.html; then
err "生产 master 环境包含测试增强脚本注入,已停止"
exit 4
fi
docker ps --filter name=filecodebox --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
log "OK: production is built from $BRANCH@$commit and ready at http://127.0.0.1:$PORT/"