DOJ is a self-hosted online judge with a React web app, a Go API server, and a Go judger/runner.
- Problems, submissions, contests, assignments, discussions, ranking, and user profiles.
- Markdown problem statements with image uploads and math rendering.
- ICPC and OI contest scoreboards, including ICPC freeze support.
- Go judger with Docker-based language containers and cgroup v2 resource measurement.
- PostgreSQL for data, Redis/Valkey for sessions and runtime state, and local or S3-compatible object storage.
The compose file starts PostgreSQL, Valkey, the DOJ server, and a local judger. The server container serves both the API and the built web app:
docker compose up -dOpen http://localhost:7974. If the database has no administrator, DOJ creates:
username: admin
password: admin
Change the default password before exposing the service.
Uploaded files, problem packages, and backups are stored in ./storage by default.
The server reads these environment variables:
| Variable | Default | Description |
|---|---|---|
DATABASE |
postgres://postgres@localhost |
PostgreSQL connection string. |
REDIS |
redis://localhost:6379/0 |
Redis or Valkey connection string. |
STORAGE |
current user home, or storage |
Local storage path, or an S3-compatible http(s) URL. |
LISTEN |
:7974 |
Server listen address. |
Storage examples:
STORAGE=/storage
STORAGE=http://access:secret@localhost:9000/doj
STORAGE=https://access:secret@s3.example.com/doj
STORAGE=https://access:secret@s3.example.com/bucket?lookup=dnslookup=dns forces virtual-host style bucket URLs. Use it only when your S3-compatible provider requires bucket names in the host.
When dist/ exists, the server serves the web app and supports history fallback for frontend routes.
The judger is Linux-only. It reads:
| Variable | Default | Description |
|---|---|---|
SERVER |
http://localhost:7974 |
DOJ server URL. |
TOKEN |
empty | Judger token created in the admin UI. |
CONCURRENCY |
1 |
Number of concurrent judging workers. |
The default compose judger shares the server container's network namespace, so it connects to 127.0.0.1 and is treated as a local judger. No token is needed for the default compose deployment.
The judger uses the same DOJ image with a different command. It is privileged, uses the host PID and cgroup namespaces, uses the host Docker socket, and mounts /var/lib/doj:/var/lib/doj. It keeps runner binaries in /var/lib/doj/bin, active work under /var/lib/doj/tasks, and problem cache under /var/lib/doj/cache/P{id}.
Install frontend dependencies once:
pnpm installRun the server:
go run . serverRun the Vite dev server:
pnpm dev --host 0.0.0.0 --port 28080Run checks:
go test ./...
pnpm test
pnpm buildRegenerate the TypeScript API schema after editing the Go-first web contract in server/web/openapi.go:
pnpm api:genThis writes the ignored OpenAPI artifact to common/web/openapi.yaml, then updates web/client/schema.ts.
Linux judger validation should also run on a Linux host with Docker and cgroup v2 available:
go test ./judger -count=1DOJ 是一个可自部署的在线评测系统,包含 React 前端、Go API 服务,以及 Go 评测机/runner。
- 题目、提交、比赛、作业、讨论、排名和用户资料。
- 支持 Markdown 题面、图片上传和数学公式渲染。
- 支持 ICPC / OI 榜单,以及 ICPC 封榜。
- Go 评测机使用 Docker 语言容器,并通过 cgroup v2 统计资源。
- 使用 PostgreSQL 存数据,Redis/Valkey 存 session 和运行态,支持本地或 S3 兼容对象存储。
compose 会启动 PostgreSQL、Valkey、DOJ server 和本地评测机。server 容器同时提供 API 和前端静态文件:
docker compose up -d打开 http://localhost:7974。如果数据库里还没有管理员,DOJ 会创建:
用户名:admin
密码:admin
正式暴露服务前请先修改默认密码。
上传文件、题目数据和备份默认存放在 ./storage。
server 读取这些环境变量:
| 变量 | 默认值 | 说明 |
|---|---|---|
DATABASE |
postgres://postgres@localhost |
PostgreSQL 连接串。 |
REDIS |
redis://localhost:6379/0 |
Redis 或 Valkey 连接串。 |
STORAGE |
当前用户 home,或 storage |
本地存储路径,或 S3 兼容 http(s) URL。 |
LISTEN |
:7974 |
server 监听地址。 |
存储配置示例:
STORAGE=/storage
STORAGE=http://access:secret@localhost:9000/doj
STORAGE=https://access:secret@s3.example.com/doj
STORAGE=https://access:secret@s3.example.com/bucket?lookup=dnslookup=dns 强制使用 bucket 子域名风格。只有对象存储服务要求 bucket 出现在 host 里时才需要它。
存在 dist/ 时,server 会提供前端静态文件,并支持前端路由的 history fallback。
评测机只支持 Linux。它读取:
| 变量 | 默认值 | 说明 |
|---|---|---|
SERVER |
http://localhost:7974 |
DOJ server 地址。 |
TOKEN |
空 | 管理页创建的评测机 token。 |
CONCURRENCY |
1 |
并发评测 worker 数。 |
默认 compose 里的评测机会共享 server 容器的网络命名空间,因此它连接 127.0.0.1,会被 server 视为本地评测机。默认 compose 部署不需要 token。
评测机使用同一个 DOJ 镜像,但用不同 command 启动。它使用 privileged 模式和宿主机 PID/cgroup namespace,挂载宿主机 Docker socket,并挂载 /var/lib/doj:/var/lib/doj。runner 二进制放在 /var/lib/doj/bin,当前评测工作目录放在 /var/lib/doj/tasks,题目缓存放在 /var/lib/doj/cache/P{id}。
首次安装前端依赖:
pnpm install启动 server:
go run . server启动 Vite:
pnpm dev --host 0.0.0.0 --port 28080运行检查:
go test ./...
pnpm test
pnpm build修改 server/web/openapi.go 里的 Go-first Web 契约后重新生成 TypeScript API schema:
pnpm api:gen该命令会把忽略的 OpenAPI 产物写到 common/web/openapi.yaml,再更新 web/client/schema.ts。
Linux 评测链路需要在具备 Docker 和 cgroup v2 的 Linux 主机上验证:
go test ./judger -count=1