Files
jiang13-bbs/deploy/CONTRACT.md
freefire 40bbad2c82 公开页补齐自引用 Canonical 与按类型的结构化数据,图片补上说明文字。
后台设置和内容编辑改成可导航布局;部署用访客 origin 生成 Canonical,避免落到容器地址。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-20 00:11:24 +08:00

92 lines
3.9 KiB
Markdown
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.
# 官方运行时契约
变更本文件中的服务名、端口、volume、环境变量,视为**运行时大版本**,须在 changelog 写明,并给出最低可升级的应用版本。不要为了省事改本地开发的 `start.bat` / 仓库根 `docker-compose.yml`。
当前应用版本见仓库根 `VERSION`(现 `0.1.0`)。最低可升级版本:无(首个官方运行时)。
## 与本地开发的边界
| | 本地开发 | 官方运行时 |
|--|----------|------------|
| Compose | 仓库根 `docker-compose.yml`,只起 Postgres,映射 `5432` | `deploy/docker-compose.yml`,项目名 `jiang13` |
| 后端 | `cd backend && go run ./cmd/jiang13`,数据 `backend/data/` | 容器 `api`,`JIANG13_WORK_PATH=/var/lib/jiang13` |
| 前端 | `cd frontend && npm run dev`,`:3000` | 容器 `web`,Next standalone `:3000` |
| 入口 | 浏览器 `http://localhost:3000` | 宿主机反代(Nginx 等)同源反代 `127.0.0.1:3000` + `127.0.0.1:3001` |
两套 Postgres volume 名字空间不同,可以并存,互不覆盖。官方 Compose **不包含**反代容器。
## 服务名(Compose)
- `postgres` — PostgreSQL 17(不映射宿主机 5432)
- `api` — Go,容器内 `3001`,默认发布 `127.0.0.1:3001`
- `web` — Next.js standalone,容器内 `3000`,默认发布 `127.0.0.1:3000`
禁止把 API 单独做到另一个子域。`/api` 与 `/api/ws` 必须由反代直达 `api`,不能进 Next(Upgrade 无法经 Next rewrite)。
## Volume
| 名 | 容器路径 | 内容 |
|----|----------|------|
| `pgdata` | `/var/lib/postgresql/data` | 数据库 |
| `appdata` | `/var/lib/jiang13/data` | 上传、`private/` 附件、`.jwt_secret` |
镜像内不放真实 `app.ini`、不放用户数据。
## 环境变量
### api
| 变量 | 必需 | 说明 |
|------|------|------|
| `HTTP_PORT` | 否 | 默认 `3001` |
| `DEV_MODE` | 是(Compose 写死 `false`) | 生产 cookie 走 `__Host-`,须反代 HTTPS |
| `JIANG13_WORK_PATH` | 是 | 固定 `/var/lib/jiang13` |
| `DATA_DIR` | 是 | 固定 `/var/lib/jiang13/data` |
| `DB_DSN` | 是 | 指向服务名 `postgres` |
| `JWT_SECRET` | 是 | 强随机;勿依赖自动生成做多副本 |
| `SITE_URL` | 建议 | 对外 origin,无尾斜杠,如 `https://bbs.example.com` |
| `CORS_ORIGINS` | 否 | 额外 origin,逗号分隔 |
### web
| 变量 | 必需 | 说明 |
|------|------|------|
| `BACKEND_URL` | 是 | 固定 `http://api:3001`(SSR / middleware,勿写成公网 URL) |
| `SITE_URL` | 建议 | 与 api 相同的对外 origin。Canonical / sitemap / robots 在**运行时**读取;不要写成 `http://api:3001` |
| `PORT` / `HOSTNAME` | 否 | `3000` / `0.0.0.0` |
| `NEXT_PUBLIC_APP_VERSION` | 构建期 | 与 `VERSION` 相同;**不要**设置 `NEXT_PUBLIC_API_URL=http://api:3001`(会泄漏到浏览器) |
浏览器 API 走同源 `/api/*`(由宿主机反代直达 Go)。WebSocket 走同源 `/api/ws`,不要设 `NEXT_PUBLIC_WS_URL`。
### 宿主机发布
| 变量 | 默认 | 说明 |
|------|------|------|
| `JIANG13_BIND` | `127.0.0.1` | 只给本机反代;需要对外直连再改 |
| `JIANG13_WEB_PORT` | `3000` | web 宿主机端口 |
| `JIANG13_API_PORT` | `3001` | api 宿主机端口 |
### 镜像 tag
`JIANG13_VERSION` 同时作为 `api`/`web` 镜像 tag。`JIANG13_IMAGE_API` / `JIANG13_IMAGE_WEB` 默认为本地名;推仓库后改成 registry 路径即可 `docker compose pull`。
`POSTGRES_PASSWORD` 会拼进 `DB_DSN`,不要包含 `@ : / # ?` 等 URL 保留字符。
## 健康检查
- `api`:`GET http://127.0.0.1:3001/health`(含 DB ping、`version`)
- `web`:`GET http://127.0.0.1:3000/healthz`(不访问后端)
## 更新
应用升级:换同一契约下的新镜像 tag,然后:
```
docker compose pull
docker compose up -d
```
新 `api` 启动时执行既有 `AutoMigrate`。接受短暂停机。上线前不为双版本并存写兼容垫片。
改 Compose / 环境变量 / volume 路径属于运行时升级,不能只 pull。