Running Judge0 in cgroup v1


Judge0 has a modular microservices-based architecture that looks something like this:
API Server (REST API)
Worker(s) (Isolated sandboxes that run user code)
Database (PostgreSQL, for metadata about submissions)
Message Queue (Redis Pub/Sub or optionally RabbitMQ)
[User submits code via frontend] → [Judge0 REST API] → [PostgreSQL]
↓
[Redis PubSub queue]
↓
[Judge0 Worker picks job]
↓
[Runs in isolated container]
↓
[Collect output/errors/time/memory usage]
↓
[Store results in PostgreSQL]
↓
[User polls or gets notified of result]
Judge0 uses isolate sandbox that creates a temporary directory like
/box
, runs the code inside it, and deletes after execution.Isolate Uses
cgroups v1
to enforce memory limits (which is why your error occurs when it can’t write to/sys/fs/cgroup/memory/box-*
).Control Groups (cgroups):
Cgroups are a Linux kernel feature that lets you limit, monitor, and isolate the resource usage (CPU, memory, disk I/O, etc.) of a process or a group of processes.
which is why
systemd.unified_cgroup_hierarchy=0
is recommended to disable cgroup v2 (which uses a unified hierarchy and doesn’t have the same memory interface layout).
Judge0 worker requires cgroup v1, and strict memory sandboxing needs:
Host with cgroupv1
/sys/fs/cgroup
to be writable (bind-mounted)privileged
mode in DockerSYS_ADMIN
,SYS_RESOURCE
capabilities
Otherwise: You’ll hit the Cannot write /sys/fs/cgroup/memory/box-N/memory.limit_in_bytes
error.
Newer versions of linux ( eg. ubuntu ) come with cgoup v2 , which offical doc. of judge0 try to buypass by updating
/etc/default/grub
. But newer versions makes it hard to fully use cgroup v1 with memory control, due to which Judge0 won’t work reliably using default Isolate configuration.Hence, local development is DOOMED !!
Solution
Creating a LOCAL VM ( like t2.micro on AWS ) with ubuntu 20.04 as it gives
full cgroup v1 write access
.Steps:
Create and ssh into VM like :
multipass launch 20.04 --name judge0-vm --memory 2G --disk 30G --cpus 3 multipass shell judge0-vm
Run in vm :
# Install dependencies sudo apt update && sudo apt upgrade -y sudo apt install ca-certificates curl gnupg lsb-release -y # Add Docker GPG key sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \ sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg # Set up repository echo \ "deb [arch=$(dpkg --print-architecture) \ signed-by=/etc/apt/keyrings/docker.gpg] \ https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # Install Docker Engine and Docker Compose Plugin sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y # Optional: run without sudo sudo usermod -aG docker $USER newgrp docker
Install judge0
wget https://github.com/judge0/judge0/releases/download/v1.13.1/judge0-v1.13.1.zip unzip judge0-v1.13.1.zip
update REDIS & PG PASSWORD in
judge0.conf
.run the judge0 stack →
docker compose up
Get vm
ip
→ubuntu@judge0-vm:~/judge0-v1.13.1$ ip a | grep inet inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host inet 10.130.253.46/24 metric 100 brd 10.130.253.255 scope global ens3 inet6 fe80::5054:ff:fe8f:bc45/64 scope link inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 inet 172.18.0.1/16 brd 172.18.255.255 scope global br-93b092c155bf inet6 fe80::8450:dbff:fe0b:96a0/64 scope link
- Use vm’s ip to communicate eg:
10.130.253.46
- Use vm’s ip to communicate eg:
Submit and GetResult
Thankyou ……………
Subscribe to my newsletter
Read articles from Ayush Kumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
