Files
blog/docker-compose.editor.yml
T

52 lines
2.3 KiB
YAML
Raw Normal View History

# 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,gitea
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"