Files
OJ2/docker/compose.school.yml
T
xuyueandClaude Opus 5.5 b046af4ba0
Deploy / deploy (push) Canceled after 0s
chore(部署): push 后先过检查再部署;判题机重启那几秒交的题不再变成系统错误;worker 挂了看得出来
按外部分析报告(reports/analysis)挑出来做的几条:
- CI 在编完前端之后跑 `bunx vp run verify`,有一项不过就不部署(必须排在编前端之后:
  前端类型检查要的 auto-imports.d.ts / components.d.ts 是 vite build 时才生成的)
- 连不上判题机(连接被拒、解析不到、被重置)时,正式判题等 2/5/10 秒重试,不再当场记成
  系统错误;超时、判题机回错、页面上的运行和自测不重试
- worker 每 10 秒刷一次「还活着」,compose 加 `oj2-api healthcheck --worker`,deploy.sh 起栈后
  也等 worker 健康(docker 不会因 unhealthy 自动重启,只是看得见、部署时拦得住)
- 三套 compose 的容器日志限 10MB × 3
- `/public/%` 这类畸形编码回 404 而不是 500;找不到的接口回统一的 JSON 错误
- 删掉没人用的「停用判题机」接口,契约不再给 task_number / is_disabled(列留在库里)
- 删掉腐化的 apps/web/tests/submitButtonState.test.ts;契约包 zod 范围对齐到 ^4.6.6
- 修几处和实际对不上的注释与文档(表数、编译并发、AST 语言数、deploy.sh 流程、校验处数)

⚠️ 改了 compose 的日志配置,这次部署会把 postgres / redis / 判题机也重建一遍,各停几秒

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 20:59:19 +08:00

138 lines
5.0 KiB
YAML
Raw 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.
# 机房。**这里没有数据库** —— 连的是服务器那台的 5445(见 compose.debian.yml)。
#
# docker compose -f docker/compose.school.yml --env-file docker/.env.school up -d --build
#
# 两个站点共用一个库,但各有各的 Redis、判题沙箱和后端。这意味着:
#
# - 判题队列是每站独立的(BullMQ 在本地 Redis 上),学生在哪边提交就在哪边判,
# 和旧后端的 Dramatiq 拓扑一致;
# - WebSocket 推送也走本地 Redis pub/sub,所以只推得到连在**本站**的学生。
# 旧后端的 Channels 也是这样,不是回归;
# - **切换那天两边都要切。** 只切一边的话,另一边的旧后端仍在读写同一个库,
# 而库结构已经按新后端迁过了。
#
# ⚠️ `DATA_DIR` 默认值 `../data` 解析出来是 **`OJ2/data`**,不是机房部署目录的 `data/`。
# 测试点(`data/backend/test_case`)和题面图片(`data/backend/public/upload`)都在旧目录里,
# 不设 `DATA_DIR` 就会挂一堆空目录上去:判题全错、图片 404。**沿用旧数据必须设它。**
# 每个容器的日志最多 3 个 10MB 的文件。docker 默认的 json-file 不设上限,判题、worker
# 天天打日志,2 核小服务器的磁盘迟早被写满 —— 磁盘一满,postgres 写不进、判题跟着失败。
x-logging: &logging
driver: json-file
options:
max-size: 10m
max-file: '3'
services:
oj-redis:
logging: *logging
image: redis:8-alpine
container_name: oj-redis
restart: always
volumes:
- ${DATA_DIR:-../data}/redis:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
oj-judge:
logging: *logging
# 自己构建的判题沙箱(go-judge + gcc / python,见 docker/judge/)。
# ⚠️ 这个 tag 不在任何 registry 上:本机 docker/judge/build.sh 构建,
# 服务器/机房用 docker load 装。镜像不在本地时 compose 会去 pull 然后报找不到。
image: oj2-judge-3
container_name: oj-judge
restart: always
# go-judge 要自己建 namespace 和 cgroup 来关学生程序,只能给特权,理由见 docker/judge/README.md
privileged: true
# go-judge 的文件存储(编译产物、程序输出)放这里,见 docker/judge/Dockerfile 的 -dir
tmpfs:
- /tmp
volumes:
- ${DATA_DIR:-../data}/backend/test_case:/test_case:ro
environment:
ES_AUTH_TOKEN: ${OJ2_JUDGE_TOKEN:?请在 env 文件里设置 OJ2_JUDGE_TOKEN}
# 机房机器内存宽裕,判题给足
mem_limit: 2g
oj-api:
logging: *logging
build: &build
context: ..
dockerfile: docker/Dockerfile
target: api
# 产物来源,见 docker/Dockerfile 顶部。默认 build(服务器自己编);
# CI 传 ARTIFACTS=prebuilt 用 runner 编好的产物。
args:
ARTIFACTS: ${ARTIFACTS:-build}
image: oj2-api:latest
container_name: oj-api
restart: always
depends_on:
oj-redis:
condition: service_healthy
volumes:
- ${DATA_DIR:-../data}/backend:/data
environment: &api-env
# 库在服务器上,走公网。DB_HOST 默认值就是服务器地址,换机器改 env 文件
DATABASE_URL: postgres://onlinejudge:${POSTGRES_PASSWORD:?}@${DB_HOST:-150.158.29.156}:${DB_PORT:-5445}/onlinejudge
REDIS_URL: redis://oj-redis:6379
JUDGE_SERVER_URL: http://oj-judge:8080
JUDGE_SERVER_TOKEN: ${OJ2_JUDGE_TOKEN:?}
# 后台「判题机列表」里这一台的名字(worker 替判题机记心跳,见 judge/heartbeat.ts)
JUDGE_SERVER_NAME: 机房
JUDGE_CONCURRENCY: ${JUDGE_CONCURRENCY:-4}
TRIAL_CONCURRENCY: ${TRIAL_CONCURRENCY:-4}
AI_KEY: ${AI_KEY:-}
AI_HINT_DIAGNOSE: ${AI_HINT_DIAGNOSE:-}
healthcheck:
test: ["CMD", "oj2-api", "healthcheck"]
interval: 30s
timeout: 3s
retries: 3
start_period: 10s
mem_limit: 4g
oj-worker:
logging: *logging
build: *build
image: oj2-api:latest
container_name: oj-worker
restart: always
depends_on:
- oj-api
volumes:
- ${DATA_DIR:-../data}/backend:/data
environment: *api-env
command: ["oj2-api", "worker"]
# worker 每 10 秒刷一次「还活着」,60 秒没刷就是挂了(oj2-api healthcheck --worker)。
# unhealthy 只是标出来、deploy.sh 起栈时会等它,docker 不会因此自动重启容器
healthcheck:
test: ["CMD", "oj2-api", "healthcheck", "--worker"]
interval: 30s
timeout: 3s
retries: 3
start_period: 20s
mem_limit: 2g
oj-web:
logging: *logging
build:
context: ..
dockerfile: docker/Dockerfile
target: web
args:
ARTIFACTS: ${ARTIFACTS:-build}
image: oj2-web:latest
container_name: oj-web
restart: always
depends_on:
- oj-api
volumes:
- ${DATA_DIR:-../data}/backend/log:/data/log
ports:
- "${WEB_PORT:-81}:8000"
mem_limit: 256m