起因:GitHub 账号被平台标记,随后仓库被按 AUP 合规条款清空 ——
远端只剩一条孤立提交(无父提交、无内容):
c21d5669 2026-10-06 20:08:32 +0800 zqlit
chore: remove repository content (AUP compliance)
同时远端 main 的历史与本地**完全分叉**:两边只共享 2024-07-11 的 Initial commit,
之后每个提交 SHA 都不同(远端那份 989 提交、剥离了 .env/私钥/大二进制)。
所以 `git push gh main` 无法快进,也不可能再当备份用。
改动:
- `git remote remove gh`(改动前配置存 .workbuddy-backup/git-remotes.20261006-201354.txt)
- `pushall` 别名 → `git push origin main; git push gitee main`
- `scripts/setup-cnb-remotes.sh`:参数化第二个远端为 Gitee,
顺带把「若残留 gh remote 就清掉」做进脚本;Gitee 凭据走 wincred
- `架构总览.md`:§2 发布旅程图、§5.2 远端表、§6 遗留待办全部改指向;
新增 §5.2 的 GitHub 退役记录(含那条孤立提交的原文)
与 §5.3「Gitee 辅仓的两条硬约束」实测核算
- `CNB构建落地方案.md`、`README.md`:远端与 pushall 说明同步
- **发布链路一起去 GitHub 化**(这几处原先都写死了 gh):
· `deploy/editor-api/bootstrap.sh` GH_URL/GH_SSH_KEY → GITEE_URL/GITEE_SSH_KEY,
remote `gh` → `gitee`,known_hosts/私钥文件名跟着改;
保留原设计:**没给私钥就自动降级成只推 origin**,不会让每次发布都报错
· `docker-compose.editor.yml` PUSH_REMOTES → origin,gitee
· `editor-api/server.mjs` 默认值 → 'origin,gitee'
· `editor-api/README.md` 变量表同步
★ 尚未解决 / 需要决策的两条 Gitee 硬约束(详见 架构总览.md §5.3):
1. **单文件 ≤ 50MB,而 `bin/linux/hugo` 是 83.1MB**
—— 不管怎么瘦身历史,只要它还跟踪在 HEAD 里,Gitee 一律拒收。
2. 单仓库 ≤ 500MB,而 `.git` 是 620MB
—— 移出那个 83MB 后 HEAD ≈ 374MB,才有余量。
另:线上 editor-api 容器的 .env 仍是 `PUSH_REMOTES=origin,gh`,
且仓库里还有一个 `gh` remote。因为推送逻辑对辅仓失败只警告、不阻断发布
(`git.mjs`:主仓成即算成),所以**线上发布没有坏**;
但要真正切到 Gitee,需要等 Gitee 仓库与私钥就位后再部署一次。
53 lines
2.3 KiB
YAML
53 lines
2.3 KiB
YAML
# editor-api —— 在线编辑文章的轻量后端
|
||
#
|
||
# 用法(在服务器上):
|
||
# 1. 把博客仓库 checkout 到 /srv/blog(git 工作区,分支 main)
|
||
# 2. 在同目录放一个 .env,写入 EDITOR_TOKEN=openssl rand -hex 32 生成的值
|
||
# 3. docker compose -f docker-compose.editor.yml up -d --build
|
||
# (回收目录会落在 /srv/editor-trash,记得先 mkdir -p /srv/editor-trash)
|
||
# 4. nginx 加 /editor-api/ 反代(见 部署清单.md),Worker 配 EDITOR_API_BASE / EDITOR_TOKEN
|
||
#
|
||
# ★ 端口只绑 127.0.0.1 —— 公网扫不到 8017,只有同机的 nginx 能转发进来。
|
||
# 这是整个安全模型的一半;另一半是「令牌只存在 Worker secret 里,浏览器拿不到」。
|
||
|
||
services:
|
||
editor-api:
|
||
build: ./editor-api
|
||
container_name: editor-api
|
||
restart: unless-stopped
|
||
ports:
|
||
- "127.0.0.1:8017:8017"
|
||
environment:
|
||
# 令牌:必须显式给,没给容器会直接退出(server.mjs 里故意的)
|
||
EDITOR_TOKEN: ${EDITOR_TOKEN:?请在同目录 .env 里设置 EDITOR_TOKEN}
|
||
BLOG_ROOT: /srv/blog
|
||
# ★ 回收站与仓库必须在**同一个挂载点**内,否则 rename 会 EXDEV
|
||
# (见下方 volumes 注释)。所以这里用宿主机路径,不再映射到 /app/trash。
|
||
TRASH_DIR: /srv/editor-trash
|
||
# 容器内监听 0.0.0.0 没关系 —— 外面那层端口映射已经把它锁在宿主机回环上了
|
||
BIND_HOST: 0.0.0.0
|
||
GIT_BRANCH: main
|
||
PUSH_REMOTES: origin,gitee
|
||
GIT_AUTHOR_NAME: blog-editor
|
||
GIT_AUTHOR_EMAIL: editor@usj.cc
|
||
MAX_UPLOAD_MB: "20"
|
||
GIT_PATHS: content,static
|
||
volumes:
|
||
# ★ 只挂**一个**父目录:仓库和回收站都在它下面。
|
||
# 容器内路径 == 宿主机路径,两者同属一个挂载点,
|
||
# 删文章时 rename(2) 才能原子完成。
|
||
# 若分开挂成 /blog 和 /app/trash 两个 bind mount,rename 必报
|
||
# EXDEV: cross-device link not permitted(哪怕宿主机同一块盘)。
|
||
- /srv:/srv
|
||
healthcheck:
|
||
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8017/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
|
||
interval: 30s
|
||
timeout: 5s
|
||
retries: 3
|
||
start_period: 10s
|
||
logging:
|
||
driver: json-file
|
||
options:
|
||
max-size: "10m"
|
||
max-file: "3"
|