Competitive programming is increasingly popular largely due to the soaring demand of software engineers and ‘coding interviews’ as a rite of passage for becoming one. A number of services have emerged to provide contest systems along with computing resources and problemsets. However, one may find that such proprietary systems are not without their limits. Domjudge is an open source platform to host programming contests. It comes with an automated judging system to run programming contests, as well as interfaces for participants (called teams) to submit their solution code ahd receive the verdict. The administrator can coordinate multiple contests simulatneously and appoint juries to oversee each contest. It supports an ACM-ICPC format and is widely adopted by ICPC regional directors and university contests.
Here we introduce how to set up an environment with LAMP. Please consult the official documentation for other settings. We employed AWS but you may build on-premises following this instruction, except that you need to do networking parts on your own.
We used Domjudge 5.3.0 here, which may well become outdated some day, and advise to use a recent but stable version for the contests.
You could put all of the above in a single instance, but it is highly discouraged. First, the Judgehosts require an exclusive usage of CPU during execution. Even though they consider the user execution time when judging the solutions, instead of the real execution time, the execution time of a submission might considerably differ due to cache misses or I/O interrupts. It makes jury onerous to set a tight time limit. (e.g. O(Nlg^2N)
should be rejected but not O(NlgN)
) Also, it is recommended to use an isolated database for security reasons, especially when you can’t rule out malicious submissions from untrusted users. For brevity, however, we will put the database into the main server in this post.
$ sudo apt update
$ sudo apt install -y gcc g++ make zip unzip php-fpm php-cli php-gd php-curl php-mbstring php-mysql php-json php-xml php-mcrypt php-zip bsdmainutils ntp linuxdoc-tools linuxdoc-tools-text groff texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended apache2 mysql-client mysql-server libapache2-mod-php libcgroup-dev
It will take several minutes. You may not install mysql-server
if you decided to use the external database server. Remember the password of mysql for later.
$ wget https://domjudge.org/releases/domjudge-5.3.0.tar.gz
$ tar -xzf domjudge-5.3.0.tar.gz
$ cd domjudge-5.3.0
$ ./configure --disable-submitclient
$ make domserver && make docs
$ sudo make install-domserver && sudo make install-docs
Now you have domserver installed at /opt/domjudge/domserver
.
$ sudo vi /opt/domjudge/domserver/etc/dbpasswords.secret
# Randomly generated on host ip-*-*-*-*, Thu Oct 26 12:03:44 UTC 2017
# Format: 'dummy:<db_host>:<db_name>:<user>:<password>'
dummy:localhost:domjudge:domjudge:_YourPasswordHere_
$ cd /opt/domjudge/domserver/bin
/* You need to change the host if you have decided to use external DB server. Otherwise, skip this. */
$ vi ./dj_setup_database
/* Replace 'localhost' to your designated server. */
$ ./dj_setup_database -u root -r bare-install
Database credentials read from '/opt/domjudge/domserver/etc/dbpasswords.secret'.
Enter password: _[Your Database User password]_
DOMjudge database and user(s) created.
Enter password: _[Your Database User password]_
SQL structure and defaults installed (no sample data).
Domjudge provides .conf
file for apache2, which is located at etc/apache.conf
.
$ sudo ln -s ~/domjudge-5.3.0/etc/apache.conf /etc/apache2/conf-available/domjudge.conf
$ sudo a2enconf domjudge
$ sudo service apache2 reload
Now you can use the web interface at your.server.address/domjudge/
.
Login as an administrator with admin/admin
. In the user
tab, you will see the judgehost
in the list. Set the password and remember it. It will be later used for setting up the judgehosts.
In the home tab, click the “Config checker” below the ‘Administrator’ section. The following is the screenshot if you’ve come through right. When clicking each tab, it will show you how to fix the involving issue. Do as it suggests. “Active contests” is okay for this moment.
$ sudo apt install gcc g++ make cmake zip unzip debootstrap php-cli php-zip php-curl php-json procps openjdk-8-jre-headless openjdk-8-jdk libcgroup-dev -y
It will take a while.
$ sudo vi /etc/default/grub.d/50-cloudimg-settings.cfg
/* In line 11 (probably), append the following */
GRUB_CMDLINE_LINUX_DEFAULT="~~~~ quiet cgroup_enable=memory swapaccount=1”
$ sudo update-grub
$ sudo reboot
This will allow domjudge to use cgroups library. If you’re using your own machines (not AWS), modify /etc/default/grub
instead of /etc/default/grub.d/50-cloudimg-settings.cfg
.
After the reboot, check if you can see a message like this:
$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-4.4.0-1022-aws root=UUID=*-*-*-* ro console=tty1 console=ttyS0 quiet cgroup_enable=memory swapaccount=1
$ wget https://www.domjudge.org/releases/domjudge-5.3.0.tar.gz
$ tar -xzf domjudge-5.3.0.tar.gz
$ sudo ./configure --enable-cgroups --disable-submitclient --with-domjudge-user=root
$ sudo make domserver && sudo make judgehost
$ sudo make install-judgehost
Now we have a binary at /opt/domjudge/judgehost
. If you want to use multiple judgehosts, repeat above for each judgehost.
$ sudo vi /opt/domjudge/judgehost/etc/restapi.secret
# Randomly generated on host ip-*-*-*-*, Thu Oct 26 12:59:58 UTC 2017
# Format: '<ID> <API url> <user> <password>'
default http://_[Your Main Server}_/domjudge/api judgehost _[Your judgehost Password]_
For security issues, the domjudge recommends using chroot
. You may skip this part if you trust users.
$ sudo vi /opt/domjudge/judgehost/bin/dj_make_chroot
/* Line 30-31 */
DISTRO="Ubuntu"
RELEASE="xenial"
/* Line 103 */
INSTALLDEBS="openjdk-8-jre-headless locales"
/* Line 132 */
INSTALLDEBS="openjdk-8-jre-headless locales"
$ sudo /opt/domjudge/judgehost/bin/dj_make_chroot
It will take several minutes depending on the server’s status. After completing, add a user and start the daemon:
$ sudo useradd -d /nonexistent -g nogroup -s /bin/false domjudge-run
$ cd /opt/domjudge/judgehost
$ sudo bin/judgedaemon
If you can see the judgehost list in the web interface, everything is done! Be sure to keep your session open during the judging. (Use tmux or the like)
You may want to check how much judging requests the hosts can handle in advance. For that, please see https://github.com/ubergeek42/domjudge-gatling. Bear in mind that each submission will cost 100% of CPU for X
times of the time limit plus domjudge overhead. Empirically, we found the following settings worked well.
# of Teams | # of Instances for Judgehosts | Disk Space (GB) |
---|---|---|
10 | 2 | 8 |
50 | 4 | 10 |
100 | 6 | 16 |
500 | 18 | 32 |
However, contestants tend to storm submissions at the later stage of the contest. It will be needed to scale out about 1.5x-3x to deliver quick verdicts throughout the contest. Prepare extra instances in advance if need be. Use non-preemptible instances.
Also, be sure to supply enough disk space. If the correct output is 500,000 32-bit integers, each will eat up several MBs in the disk.
Spotboard is a modern-style, web-based scoreboard application for programming contests, notably ACM-ICPC. It has been officially used in the ACM-ICPC Regional of South Korea since 2015. Please follow the link to couple it with Domjudge.