0%

通过 Docker 部署 DOMjudge

给院赛配置的DOMjudge,使用Docker部署,记录配置过程。

Domjudge 介绍

DOMjudge 是一个用于举办编程竞赛的系统,如 ICPC 地区和世界总决赛编程竞赛。

这通常意味着参赛队在现场有固定的时间(大多为 5 小时)和一台计算机来解决一定数量的问题(大多为 8-12 个)。解决问题的方法是用一种允许使用的语言编写一个程序,根据问题输入规范读取输入,并写出正确的相应输出。

评审工作通过向评审团提交解决方案的源代码来完成。评审团系统会自动编译和运行程序,并将程序输出与预期输出进行比较。

该软件可用于处理此类竞赛中的提交和评审工作。它还可以处理对参赛队的反馈和问题沟通(澄清请求)。它为评审团、参赛队(他们的提交和澄清请求)和公众(记分牌)提供了网络接口。

官方手册 DOMjudge Manual
Docker Image domjudge/domserver

环境准备

检查更新

1
sudo apt update && sudo apt upgrade

安装 Docker

1
2
curl -fsSL https://test.docker.com -o test-docker.sh
sudo sh test-docker.sh

非root用户使用 Docker

1
2
3
sudo groupadd docker
sudo gpasswd -a ${USER} docker
sudo service docker restart

配置

参考 domjudge/domserverDOMjudge 的 domserver 和 judgehost 的 docker 安装

设置本机 cgroups,编辑 /etc/default/grub 文件,修改

1
2
- GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
+ GRUB_CMDLINE_LINUX_DEFAULT="quiet cgroup_enable=memory swapaccount=1 isolcpus=2 systemd.unified_cgroup_hierarchy=0"

更新 grub 配置

1
sudo update-grub

重启系统

1
sudo reboot

配置 MariaDB

MySQL innodb_log_file & max_allowed_packet 错误分析(若不感兴趣直接按下述建议步骤执行即可)

在产生错误的环境下进入前端的 Config checker 查看

config-checker入口

发现选项 MySOL settings 存在标红报错的情况:

MySOL settings

点进去查看,提示信息为:

1
2
MySQl's innodb_log_file size is set to 4 MB. You may want to raise this to 10x tm of the test case size and output (storage) limit (now 48 8 MB)
MySQL's max_allowed_packet is set to 2 KB. You may want to raise this to about twice the maximum of the test case size and output (storage) limit (currently 48.8MB)

这会导致在上传超过 2KB 的文件时会产生类似 SQLSTATE[HY000]: General error. 2006 MySQL server has gone away 的错误。

此时需要去修改数据库容器 dj-mariadb 的配置,从命令 docker exec -it dj-mariadb mariadb -u root -p 进入容器数据库并输入前面设置的 MYSQL_ROOT_PASSWORD 。再通过 show variables like 'max_allowed_packet'; 查看数据库当前的配置大小:

1
2
3
4
5
6
7
MariaDB [(none)]> show variables like 'max_allowed_packet';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| max_allowed_packet | 2048 |
+--------------------+-------+
1 row in set (0.002 sec)

对应地需要修改这个配置参数到需要的大小。

配置 MariaDB,需要在宿主机新建配置文件,文件这里以 /dbconfig/dj-mariadb.cnf 为例,配置如下:

新建文件并编辑保存:

1
2
sudo mkdir /dbconfig
sudo nano /dbconfig/dj-mariadb.cnf

文件内容如下,其中 max_allowed_packetinnodb_log_file_size 可根据实际需要修改,其单位可以是 MG 等,这里开了 1G

1
2
3
[mariadb]
max_allowed_packet=1G
innodb_log_file_size=3G

配置 dj-mariadb 容器

1
docker run -d -it --name dj-mariadb -v </PATH/TO/CONFIG>:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=<DB_ROOT_PWD> -e MYSQL_USER=domjudge -e MYSQL_PASSWORD=<DB_PWD> -e MYSQL_DATABASE=domjudge -p 13306:3306 mariadb --max-connections=1000
  • </PATH/TO/CONFIG>:配置文件所在路径
  • <DB_ROOT_PWD>:数据库 root 用户密码
  • <DB_PWD>:数据库 domjudge 用户密码

填充合适参数配置后的命令示例:

1
docker run -d -it --name dj-mariadb -v /dbconfig:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_USER=domjudge -e MYSQL_PASSWORD=123456 -e MYSQL_DATABASE=domjudge -p 13306:3306 mariadb --max-connections=1000

配置 DOMserver

配置 DOMserver

1
docker run -d --link dj-mariadb:mariadb -it -e MYSQL_HOST=mariadb -e MYSQL_USER=domjudge -e MYSQL_DATABASE=domjudge -e MYSQL_PASSWORD=<DB_PWD> -e MYSQL_ROOT_PASSWORD=<DB_ROOT_PWD> -e CONTAINER_TIMEZONE=Asia/Shanghai -p 12345:80 --name domserver domjudge/domserver:latest

填充对应参数后的命令示例:

1
docker run -d --link dj-mariadb:mariadb -it -e MYSQL_HOST=mariadb -e MYSQL_USER=domjudge -e MYSQL_DATABASE=domjudge -e MYSQL_PASSWORD=123456 -e MYSQL_ROOT_PASSWORD=123456 -e CONTAINER_TIMEZONE=Asia/Shanghai -p 12345:80 --name domserver domjudge/domserver:latest

若想映射到 80 端口,将上述命令中的 -p 12345:80 改为 -p 80:80 即可。

查看 admin 密码,若发现密码是 [unknown],则删掉 domserver 容器,重新构建 domserver 容器后尽快执行命令查看密码。

1
docker exec -it domserver cat /opt/domjudge/domserver/etc/initial_admin_password.secret

访问 http://localhost:12345,使用 admin 用户登录,密码为上一步查看到的 admin 密码。到这一步,DOMjudgeweb 界面已经可以正常访问了。

查看 APIsecret

1
docker exec -it domserver cat /opt/domjudge/domserver/etc/restapi.secret

配置 judgehost

配置 judgehost

1
docker run -d -it --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro --name judgehost-0 --link domserver:domserver --hostname judgedaemon-0 -e DAEMON_ID=0 -e CONTAINER_TIMEZONE=Asia/Shanghai -e JUDGEDAEMON_PASSWORD=<JUDGE_SECRET> domjudge/judgehost:latest

填充上一步查看到的 APIsecret 后的命令示例:

1
docker run -d -it --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro --name judgehost-0 --link domserver:domserver --hostname judgedaemon-0 -e DAEMON_ID=0 -e CONTAINER_TIMEZONE=Asia/Shanghai -e JUDGEDAEMON_PASSWORD=03KXmTdxmKRsUDol3uwmp6z+BkA/uHDi domjudge/judgehost:latest

配置多个 judgehost 时,只需要将上面的 0 改为对应的 ID 即可。

使用建议

给docker加上自动重启

1
2
3
docker update --restart=always dj-mariadb
docker update --restart=always domserver
docker update --restart=always judgehost-0

欢迎关注我的其它发布渠道