How to Self-Host Judge0 — Understand Why It Doesn’t Work Properly in WSL

Sohan ChaudhariSohan Chaudhari
7 min read

What is Judge0?

Judge0 is an open source project maintained by respective Herman Zvonimir Došilović. It is a code execution engine which supports 60+ programming languages. Easy to deploy and use it as API via HTTP requests. It holds potential for powering up online IDEs, evaluation of code solutions etc.


Requirements

  • OS: For Judge0 v1.13.1, Ubuntu 22.04 is recommended!

  • CPU: 1 core for testing purpose, 2 or more cores for real world use case.

  • RAM: 1GB for testing purpose, 2 or more gigabytes of ram for real world use case.

  • DISK: 14GB+

  • OTHERS: Internet, Docker, Swap(Optional but useful if memory is limited)


💡
Firstly ensure that linux/ubuntu 22.04 system is up and active either through Linode/Digital Ocean or via VMWARE/Virtual Box. Connect with the system through the local terminal with the help of SSH.

Initial Setup

Packages

Update and upgrade the packages.

sudo apt update && sudo apt upgrade -y

Install docker, docker-compose, git and unzip.

sudo apt install docker docker-compose git unzip -y

Virtual Memory Setup (Optional)

Consider enabling virtual memory using swap if your system has 1GB or less RAM.. Though it is slower than ram but can prove useful for memory management.

navigate to root directory.

cd /

Allocate disk space as virtual memory. Ensure whether target size for allocating as virtual memory is freely available as disk space!

sudo fallocate -l 2G /swapfile #2G can be replaced with any number such as 7G to allocate that much space

Set read and write permissions for /swapfile.

sudo chmod 600 /swapfile

Prepare the /swapfile as swap space. Basically tell the system to format this file in such manner that system can store unused pages i.e. the unused data of less active processes from memory into this file.

sudo mkswap /swapfile

Start/initiate/execute /swapfile as virtual memory

sudo swapon /swapfile

Till previous step, everything was set for the current boot. The changes won’t stay after the reboot. So to set this virtual memory aka swap file permanent open fstab file with nano editor and append /swapfile none swap sw 0 0 to new line

sudo nano /etc/fstab

Run this command to check whether swap/virtual memory has been activated or not

free -h


Judge0 and cgroup Compatibility: Why WSL Isn’t a Suitable Environment

Right now the version of Judge0 i.e. v1.13.1 has clean compatibility with Ubuntu 22.04. It may or may not work with other versions of Linux Distributions.

But here’s the catch!

There is a concept of cgroups in linux which stands for Control Groups. cgroups are used for allocating system resources such as CPU, Memory, I/O to a process or set of processes. There are 2 versions of cgroups i.e. cgroup v1 and cgroup v2.

cgroup v1

In cgroup v1 style of resource allocation, we can think of it like the resources are represented as categories — like CPU, memory, I/O — and each category has its own hierarchy of groups. Those categories are referred as resource controllers in technical terms. You can create multiple groups under each resource, each with a specific share of that resource and then assign processes to particular groups of resources.

cgroup v2

In cgroup v2, things are simpler and more organized. There's just one main system to manage everything. You can set limits on different resources like CPU and memory all in one place. For example, you can give Group A 50% of the CPU and 25% of the memory, while Group B gets 25% CPU and 50% memory. This makes it easier to manage and more predictable.

Judge0 v1.13.1 cgroup’s compatibility

cgroup v1 has been discontinued since 2016 in linux distributions and have started coming up cgroup v2 as default. Yet many softwares still rely on cgroup v1 and Judge0 is one of those.

Hence first we need to check which cgroup version is the os using right now via following command.

mount | grep cgroup

If output is something like this cgroup2 on /sys/fs/cgroup type cgroup2 then it means, the linux environment is using cgroup v2. So for deploying Judge0 we need to change it to cgroup v1.


💡
What Happens If Judge0 Is Deployed with cgroup v2

Even with cgroup Judge0 will get deployed properly and it’s containers will be up and running. The main issue occurs when code is sent to Judge0 for execution, it would throw internal error with code 13 even though the code is correct and has no errors.

{
  stdout: null,
  time: null,
  memory: null,
  stderr: null,
  token: '4415994e-960e-4a6c-897a-5604c9570db1',
  compile_output: null,
  message: 'No such file or directory @ rb_sysopen - /box/script.js',
  status: { id: 13, description: 'Internal Error' }
}

This is how the response would look like, especially the message key which clearly states, something is wrong!


We need to add a configuration in GRUB file of the linux distribution.

So for making the configuration first open the grub file in nano editor via following command, and add this variable GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=0"

sudo nano /etc/default/grub

Apply changes through this command

sudo update-grub

And then reboot

sudo reboot

Now check cgroup version again with this command

mount | grep cgroup

Terminal should respond with multiple prints of something like this cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup and this means the cgroup version is successfully changed to v1.


💡
Why Judge0 Deploys But Can’t Execute Code Properly on WSL

In order to make this work, you need a proper Linux system with a working bootloader. However, in environments like WSL (Windows Subsystem for Linux), Windows bypasses the bootloader and directly loads the Linux kernel through an underlying virtual machine (VM). WSL simulates the userland based on the distribution, and by default, it uses cgroupv2, which is managed by Microsoft and cannot be changed by users. The Linux kernel in WSL is also provided and maintained by Microsoft, ensuring compatibility with Windows. Therefore, changes to the GRUB configuration or cgroup settings have no effect in WSL, unlike on a native Linux installation


Deploying Judge0

Download Judge0 release zip file

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

unzip the file

unzip judge0-v1.13.1.zip

relocate inside extracted folder

cd judge0-v1.13.1

Add Postgres and Redis password by editing judge0.conf file

sudo nano judge0.conf

To generate random passwords, try this link!

Add password and save via CTRL + O after that press Enter to save.

Exit the editor by pressing CTRL + X

Later, Compose up containers for Redis and Postgres

docker-compose up -d db redis

After a while compose up the servers and workers

docker-compose up -d

Check the status of containers to confirm whether they are up and running

docker ps


Exposing Port To Internet & Enabling Firewall

If you are on online vm of linux or anything then you should consider enabling firewall and exposing a port to internet. You can also skip this if you are on local machine.

We need to make the port available to internet for making http requests to our deployed Judge0 server from our backend.

Check firewall status.

sudo ufw status

If the ufw status is inactive then you can activate the firewall by the following command

sudo ufw enable

Once firewall is enabled, you can easily add any port number to allow list for public with this command

sudo ufw allow 2358 # Replace the port number with anyother number
                    # 2358 is default port number when Judge0 server is up and running through docker
sudo ufw delete allow 2358 # For deleting allowed port

Once enabled firewall or allowed the port, check the status again

sudo ufw status

# Expected Output
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere
2358                       ALLOW       Anywhere

Final Testing: Is Judge0 Working and Accessible?

Try opening your public server ip with port number and /docs.

# Example
http://yourPublicIpAddressOfLinuxServer:yourPortNumberOfDeployedJudge0/docs

If a documentation page of Judge0 opens up at the endpoint, then Judge 0 containers are up and running successfully!

A domain name can be assigned for this ip address.

Later try performing http request via postman with code to the deployed Judge0 server and analyse the response.


Wrapping Up….

With Judge0 up and running, you’ve unlocked the core of a custom coding platform. It’s fast, language-agnostic, and fully in your hands. From here, you can build anything from online judges to educational tools with complete control over how code is executed.

0
Subscribe to my newsletter

Read articles from Sohan Chaudhari directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sohan Chaudhari
Sohan Chaudhari