diff --git a/deploy/1panel/DEPLOY.md b/deploy/1panel/DEPLOY.md new file mode 100644 index 0000000..468060b --- /dev/null +++ b/deploy/1panel/DEPLOY.md @@ -0,0 +1,49 @@ +# FileCodeBox 部署脚本 + +## 测试环境一键部署 + +当你在 `test/custom-admin-ui` 分支改完测试环境代码后,执行: + +```bash +deploy-filecodebox-test +``` + +脚本行为: + +- 使用 `/opt/src/filecodebox` 当前工作区内容构建测试镜像。 +- 同步 `deploy/1panel/current-app/custom/fcb_extra_patch.py` 到测试环境。 +- 重建并启动 `filecodebox-test`。 +- 测试地址绑定在本机:`127.0.0.1:40158`。 +- 不影响生产容器 `filecodebox`。 + +如果需要重新从生产复制一份数据到测试环境: + +```bash +COPY_PROD_DATA=1 deploy-filecodebox-test +``` + +## 生产环境官方重建 + +生产环境默认保持官方镜像,不直接部署测试分支代码。 + +如果只是让生产回到/更新官方镜像,执行: + +```bash +CONFIRM=YES deploy-filecodebox-prod-official +``` + +脚本行为: + +- 备份生产 `docker-compose.yml` 和 `data/filecodebox.db`。 +- 确认生产 Compose 使用 `lanol/filecodebox:beta`。 +- 重建/重启生产容器。 +- 验证生产首页不包含 `fcb-analytics.js` 测试脚本。 + +## 推荐流程 + +1. 在 `test/custom-admin-ui` 分支修改代码。 +2. 执行 `deploy-filecodebox-test`。 +3. 在测试页面确认没问题。 +4. 提交测试分支。 +5. 通过 PR/合并进入 `master`。 +6. 生产仍使用官方镜像;除非明确决定发布自定义生产镜像,否则只执行官方重建脚本。 diff --git a/deploy/1panel/prod-official/deploy-prod-official.sh b/deploy/1panel/prod-official/deploy-prod-official.sh new file mode 100755 index 0000000..d985b32 --- /dev/null +++ b/deploy/1panel/prod-official/deploy-prod-official.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +set -euo pipefail + +PROD_DIR="${PROD_DIR:-/opt/1panel/apps/filecodebox/filecodebox}" +IMAGE="${IMAGE:-lanol/filecodebox:beta}" +PORT="${PORT:-40157}" +CONFIRM="${CONFIRM:-}" + +log() { printf '\033[1;32m[deploy-prod-official]\033[0m %s\n' "$*"; } +err() { printf '\033[1;31m[deploy-prod-official]\033[0m %s\n' "$*" >&2; } + +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' +这是生产环境脚本,只做“官方镜像重建/更新”,不会部署测试分支改动。 + +如确认执行,请使用: + CONFIRM=YES deploy-filecodebox-prod-official +EOF + exit 2 +fi + +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-official.$TS" +if [[ -f data/filecodebox.db ]]; then + cp -a data/filecodebox.db "backups/filecodebox.db.before-prod-official.$TS" +fi + +log "ensure official image in compose: $IMAGE" +python3 - </dev/null +log "pull official image if available" +docker pull "$IMAGE" || true + +log "recreate production container" +docker compose up -d --no-build + +log "wait for http://127.0.0.1:$PORT/" +for i in $(seq 1 30); do + if curl -fsS "http://127.0.0.1:$PORT/" >/tmp/filecodebox-prod-index.html; then + break + fi + sleep 1 + if [[ "$i" == "30" ]]; 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 "生产环境仍包含测试增强脚本注入,已停止" + exit 4 +fi + +docker ps --filter name=filecodebox --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}' +log "OK: production is official image and ready at http://127.0.0.1:$PORT/" diff --git a/deploy/1panel/test-env/deploy-test.sh b/deploy/1panel/test-env/deploy-test.sh new file mode 100755 index 0000000..16cfa51 --- /dev/null +++ b/deploy/1panel/test-env/deploy-test.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPO_DIR="${REPO_DIR:-/opt/src/filecodebox}" +TEST_DIR="${TEST_DIR:-/opt/1panel/apps/filecodebox/filecodebox-test}" +PROD_DIR="${PROD_DIR:-/opt/1panel/apps/filecodebox/filecodebox}" +BRANCH="${BRANCH:-test/custom-admin-ui}" +IMAGE="${IMAGE:-local/filecodebox:test-custom-admin-ui}" +PORT="${PORT:-40158}" +COPY_PROD_DATA="${COPY_PROD_DATA:-0}" + +log() { printf '\033[1;34m[deploy-test]\033[0m %s\n' "$*"; } +err() { printf '\033[1;31m[deploy-test]\033[0m %s\n' "$*" >&2; } + +require_cmd() { + command -v "$1" >/dev/null 2>&1 || { err "missing command: $1"; exit 1; } +} + +require_cmd git +require_cmd docker +require_cmd curl + +log "repo: $REPO_DIR" +cd "$REPO_DIR" + +current_branch="$(git rev-parse --abbrev-ref HEAD)" +if [[ "$current_branch" != "$BRANCH" ]]; then + err "当前分支是 $current_branch,不是 $BRANCH。请先切到测试分支:git checkout $BRANCH" + exit 2 +fi + +if ! git diff --quiet || ! git diff --cached --quiet; then + log "检测到未提交改动:会用当前工作区内容构建测试镜像" +fi + +log "sync test deployment directory" +mkdir -p "$TEST_DIR/custom" "$TEST_DIR/data" +cp -a deploy/1panel/current-app/custom/fcb_extra_patch.py "$TEST_DIR/custom/fcb_extra_patch.py" +cp -a deploy/1panel/test-env/Dockerfile "$TEST_DIR/custom/Dockerfile" +cp -a deploy/1panel/test-env/docker-compose.yml "$TEST_DIR/docker-compose.yml" + +if [[ "$COPY_PROD_DATA" == "1" ]]; then + log "refresh test data from production copy" + mkdir -p "$TEST_DIR/backups" + if [[ -f "$TEST_DIR/data/filecodebox.db" ]]; then + cp -a "$TEST_DIR/data/filecodebox.db" "$TEST_DIR/backups/filecodebox.db.before-refresh.$(date +%Y%m%d%H%M%S)" + fi + rsync -a --delete "$PROD_DIR/data/" "$TEST_DIR/data/" +fi + +log "build $IMAGE" +cd "$TEST_DIR" +docker compose build filecodebox-test + +log "start/recreate test container" +docker compose up -d --no-build filecodebox-test + +log "wait for http://127.0.0.1:$PORT/" +for i in $(seq 1 30); do + if curl -fsS "http://127.0.0.1:$PORT/" >/tmp/filecodebox-test-index.html; then + break + fi + sleep 1 + if [[ "$i" == "30" ]]; then + err "test environment did not become ready" + docker logs --tail 80 filecodebox-test || true + exit 3 + fi +done + +log "verify custom asset" +if ! grep -q 'fcb-analytics.js' /tmp/filecodebox-test-index.html; then + err "测试环境没有加载 fcb-analytics.js,部署异常" + exit 4 +fi + +docker ps --filter name=filecodebox-test --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}' +log "OK: test environment is ready at http://127.0.0.1:$PORT/"