onlinecompiler.io

How to self-host Judge0

Judge0 is free to self-host under GPL-3.0. The official install takes a Linux server booted with cgroup v1, Docker Compose and the v1.13.1 release; keeping it safe is the part that never ends. These steps follow Judge0's own deployment procedure, checked on 8 November 2026.

What you need

  • A Linux server or VM whose boot settings you control. Judge0 is tested only on Linux and recommends Ubuntu 22.04 (deployment procedure). WSL2, Docker Desktop and managed container hosts don't work, because they can't give it cgroup v1 (why).
  • systemd older than 256, or one extra flag. Check with systemctl --version. Ubuntu 22.04 ships 249 and 24.04 ships 255, which is fine. systemd 256 and 257 boot with cgroup v1 only when SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1 is also on the kernel command line, and 258 removed cgroup v1, so Judge0 1.13.1 can't run as documented there.
  • Docker and Docker Compose, with privileged containers allowed. Judge0's server and workers run privileged: true, next to PostgreSQL 16.2 and Redis 7.2.4 (docker-compose.yml).
  • A server of its own. A privileged container means a sandbox escape reaches the host, so don't run anything else on it.

1. Boot the host with cgroup v1

Ubuntu 22.04 and later start with cgroup v2. Judge0's sandbox needs v1, so add the setting to GRUB and reboot. On systemd 256 or 257, add SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1 to the same line.

Terminal
# /etc/default/grub: add the setting to GRUB_CMDLINE_LINUX
GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=0"

sudo update-grub
sudo reboot

# After the reboot, cgroup v1 controllers such as /sys/fs/cgroup/memory should be listed
mount | grep cgroup

2. Download Judge0 and set its passwords

Judge0 ships as a release archive with a docker-compose.yml and a judge0.conf. Its procedure asks for a random password for Redis and another for PostgreSQL.

Terminal
wget https://github.com/judge0/judge0/releases/download/v1.13.1/judge0-v1.13.1.zip
unzip judge0-v1.13.1.zip
cd judge0-v1.13.1

# Two random passwords for judge0.conf (any 32 random characters will do)
openssl rand -hex 16   # set as REDIS_PASSWORD
openssl rand -hex 16   # set as POSTGRES_PASSWORD
judge0.conf
# judge0.conf
REDIS_PASSWORD=...         # the first password
POSTGRES_PASSWORD=...      # the second password
AUTHN_TOKEN=...            # a long random token: without one, anyone who reaches the port can run code
JUDGE0_TELEMETRY_ENABLE=false   # optional: telemetry is on by default

Two settings the procedure doesn't mention matter on a server others can reach. AUTHN_TOKEN is empty by default, which turns authentication off (judge0.conf), so set it and send the token in X-Auth-Token. Telemetry is on by default; JUDGE0_TELEMETRY_ENABLE=false turns it off (TELEMETRY.md).

3. Start it

Start the database and Redis first, then the server and workers:

Terminal
docker-compose up -d db redis
sleep 10s
docker-compose up -d
sleep 5s
# The API docs are now at http://YOUR_SERVER:2358/docs
# (with Docker Compose v2, the command is "docker compose")

The workers run in parallel, 2 × nproc of them unless you set COUNT in judge0.conf.

4. Send a test submission

A self-hosted install lets you wait for the result in the same request (wait=true). Language 71 is Python 3.8.1 in Judge0 CE:

Terminal
curl -X POST "http://localhost:2358/submissions?base64_encoded=false&wait=true" \
  -H "X-Auth-Token: YOUR_AUTHN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"language_id": 71, "source_code": "print(int(input()) * 2)", "stdin": "21", "expected_output": "42"}'

# ... "stdout": "42\n", "status": {"id": 3, "description": "Accepted"}

If it answers status 13, Internal Error, with "No such file or directory @ rb_sysopen", the host is still on cgroup v2: see the cgroup v2 error.

Keeping it running

  • Security fixes: v1.13.1 fixed three critical sandbox escapes (CVE-2024-28185, CVE-2024-28189 and CVE-2024-29021), so never run an older release. It is still the latest (releases), from 18 April 2024, so watch the repository's advisories yourself.
  • Language versions are the ones in the release's image; newer ones mean building your own.
  • Capacity: each worker runs one submission at a time, so a deadline rush queues up. Watch the queue and add workers or servers before a busy week.
  • Backups: submissions live in PostgreSQL, in the compose file's data volume.
  • Distribution upgrades can bring a systemd that won't boot with cgroup v1 (see above), so check systemctl --version and mount | grep cgroup after each one.

Or skip the server

If you only needed Judge0's API, not your own copy of it, there are hosted options. Judge0 sells daily quotas on judge0.com and RapidAPI (every plan). OnlineCompiler.io answers Judge0 CE's API at https://api.onlinecompiler.io/api/judge0: change the base URL, send your key in X-Auth-Token, and submissions, tokens, wait=true, batches and status ids work as before. Each run gets a fresh gVisor sandbox with no network and up to 512 MB, and the free plan includes 100,000 runs a month with commercial use. It runs fewer languages than Judge0, so check yours in the migration guide first. To compare the two open-source engines, see Piston vs Judge0.

Frequently asked questions

Is Judge0 free to self-host?

Yes. Judge0 is open source under GPL-3.0, so the software costs nothing. You pay for the server, and for the time it takes to install, secure, update and scale it.

What server does Judge0 need?

A Linux server or VM whose boot settings you control, booted with cgroup v1, with Docker and Docker Compose and permission to run privileged containers. Judge0 recommends Ubuntu 22.04. WSL2, Docker Desktop and most managed container hosts cannot give it cgroup v1.

Does Judge0 work on Ubuntu 24.04?

With the same GRUB change as on 22.04. Ubuntu 24.04 ships systemd 255, which still boots with cgroup v1. From systemd 256 the force flag SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1 is also needed, and systemd 258 removed cgroup v1, so on a distribution with 258 or later Judge0 1.13.1 cannot run as documented.

Why does every submission return Internal Error?

Almost always because the host uses cgroup v2, so the sandbox cannot be created and the worker cannot write your source file ("No such file or directory @ rb_sysopen - /box/script.py"). See the cgroup v2 error page for the causes and workarounds.

How do I turn off Judge0 telemetry?

Set JUDGE0_TELEMETRY_ENABLE=false in judge0.conf and restart the containers. Telemetry is on by default, according to Judge0's TELEMETRY.md.

Is there a hosted Judge0 instead?

Judge0 sells hosted plans by the day on judge0.com and RapidAPI. OnlineCompiler.io answers Judge0 CE's API at https://api.onlinecompiler.io/api/judge0, so a Judge0 client moves by changing its base URL and key, with 100,000 free runs a month.