警告
本文发表于 2018 年底,DOMJudge 的代码已进行了大规模的重构,部分内容可能过时。
EC-Final 结束之后就一直是咸鱼状态。然后就自己挖了个坑,学习配置了一下 DOMjudge。
于是水一篇博文来记录一下过程中遇到的各种坑。
官网已经更新到 7.1.1 版本,以下内容可能过时,最新内容请参考此处 。
注释
Docker 还是方便,偷懒的话可以用 Docker 一键部署。
docker-compose.yaml
version: '2'
services:
mariadb:
image: mariadb
restart: always
volumes:
- $PWD/data/mysql:/var/lib/mysql
ports:
- 13306:3306
environment:
- CONTAINER_TIMEZONE=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=adm1n
- MYSQL_USER=domjudge
- MYSQL_PASSWORD=passw0rd
- MYSQL_DATABASE=domjudge
command: --max-connections=1000
domserver:
image: domjudge/domserver:latest
restart: always
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
links:
- mariadb:mariadb
ports:
- 12345:80
environment:
- CONTAINER_TIMEZONE=Asia/Shanghai
- MYSQL_HOST=mariadb
- MYSQL_ROOT_PASSWORD=adm1n
- MYSQL_USER=domjudge
- MYSQL_PASSWORD=passw0rd
- MYSQL_DATABASE=domjudge
judgehost_0:
image: domjudge/judgehost:latest
restart: always
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
links:
- domserver:domserver
environment:
- CONTAINER_TIMEZONE=Asia/Shanghai
- DAEMON_ID=0
- JUDGEDAEMON_USERNAME=judgehost
- JUDGEDAEMON_PASSWORD=judgeh0st
privileged: true
judgehost_1:
image: domjudge/judgehost:latest
restart: always
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
links:
- domserver:domserver
environment:
- CONTAINER_TIMEZONE=Asia/Shanghai
- DAEMON_ID=1
- JUDGEDAEMON_USERNAME=judgehost
- JUDGEDAEMON_PASSWORD=judgeh0st
privileged: true
版本与环境
版本 | 环境 |
---|---|
Ubuntu 16.04 LTS | DOMjudge 6.0.3 |
DOMserver 部分
准备工作
这部分其实就是朗读了一遍文档,直接按文档搞就好了。
安装依赖包和功能
sudo apt install gcc g++ make zip unzip mariadb-server \
apache2 php php-cli libapache2-mod-php php-zip \
php-gd php-curl php-mysql php-json php-xml php-intl php-mbstring \
acl bsdmainutils ntp phpmyadmin python-pygments \
libcgroup-dev linuxdoc-tools linuxdoc-tools-text \
groff texlive-latex-recommended texlive-latex-extra \
texlive-fonts-recommended texlive-lang-european
安装时选择 apache2
。
sudo apt install libcurl4-gnutls-dev libjsoncpp-dev libmagic-dev
sudo phpenmod json
编译 DOMjudge
wget https://www.domjudge.org/releases/domjudge-6.0.3.tar.gz
tar -zxvf domjudge-6.0.3.tar.gz
cd domjudge-6.0.3
./configure --prefix=$HOME/domjudge --with-baseurl=127.0.0.1
make domserver && sudo make install-domserver
make judgehost && sudo make install-judgehost
make docs && sudo make install-docs
配置数据库
cd ~/domjudge/domserver
sudo bin/dj_setup_database -u root install
配置 Web 服务器
cd ~/domjudge/domserver
sudo ln -s /home/ubuntu/domjudge/domserver/etc/apache.conf /etc/apache2/conf-available/domjudge.conf
sudo a2enmod rewrite
sudo a2enconf domjudge
sudo systemctl reload apache2
这里的ubuntu
是我的实际用户名。
到这里,就可以访问http://127.0.0.1/domjudge
,并使用admin
作为用户名和密码登陆后台了。
如果需要使用类似domjudge.example.com
的形式访问,可以根据domjudge.conf
中的注释,来配置虚拟服务器。
配置 MySQL
编辑/etc/mysql/my.cnf
,追加内容:
[mysqld]
max_connections = 1000
max_allowed_packet = 16MB
innodb_log_file_size = 48MB
其中 max_allowed_packet
数值改成两倍于题目测试数据文件的大小,innodb_log_file_size
数值改成十倍于题目测试数据文件的大小。
sudo systemctl restart mysql
配置 PHP
编辑 ~/domjudge/domserver/etc/apache.conf
,取消以下几行内容前的注释:
<IfModule mod_php7.c>
php_value max_file_uploads 100
php_value upload_max_filesize 128M
php_value post_max_size 128M
php_value memory_limit 512M
</IfModule>
编辑 /etc/php/7.2/apache2/php.ini
,搜索 date.timezone
关键字,取消其行前注释,并将其值设为 Asia/Shanghai
。
sudo systemctl restart apache2
配置 Apache
编辑 /etc/apache2/apache2.conf
,搜索 KeepAlive
关键字,将其值设为 Off
,并在其后新增一行内容:
MaxClients 1000
sudo systemctl restart apache2
配置 DOMserver
访问 http://127.0.0.1/domjudge
(或者外网IP/域名),使用用户名admin
密码admin
登陆。
修改 admin 密码
访问 users 页面,点 admin
用户边上的铅笔图标,在 Password 栏中输入新密码,保存。
配置设置
添加队伍和账号
- 去年学长搞的时候是直接拿SQL语句操作数据库的。(大声
- 先导入
teams.tsv
再导入accounts.tsv
。 文件编码要用UTF-8
。 - 具体格式可以参考这个 。
如果使用系统默认的Group
,那么teams表中的Group_ID
就全部填 $3$,表示participants
,其它情况按需要调整。
accounts
表中的username
是team01
的形式就可以和team表对应上。(可能还有其它方法对应)
如果需要使用学校的校徽,可以放在~/domjudge/domserver/webapp/web/images/affiliations
文件夹下。
图片大小需要自行调整,文件名为<ExternalID>.png
。
在导入teams表的时候,在Country Code
后追加一列,填写Institution External ID
。
这步是阅读源代码
后猜测的,当时的实际操作是直接在数据库中的team_affiliation
用SQL语句更新ExternalID
的。
更正:在导入teams表的时候,如果有多个学校(即使不用校徽),必须要有 Institution External ID ,似乎是因为这部分对空值的处理有一些问题。
这部分实际上比较迷,建议研究一下DOMjudge的数据库结构和源代码,一般情况下我觉得读到这里的同学有能力自行解决。(小声
生成队伍密码
访问 home 页面,点 Manage team passwords
,选中 all teams
和 as userdata.tsv download
。
注意生成过的密码除了 userdata.tsv
不能在其他地方再被看到。
Judgehost 部分
准备工作
安装依赖包和功能
sudo apt install make sudo debootstrap libcgroup-dev \
php-cli php-curl php-json php-xml php-zip procps \
gcc g++ openjdk-8-jre-headless \
openjdk-8-jdk ghc fp-compiler \
libcurl4-gnutls-dev libjsoncpp-dev libmagic-dev \
supervisor
编译 DOMjudge
这里只针对单独配置 Judgehost 的机器,前面 DOMserver 配置中已经同时安装了 Judgehost。
cd Downloads
wget https://www.domjudge.org/releases/domjudge-6.0.3.tar.gz
tar -zxvf domjudge-6.0.3.tar.gz
cd domjudge-6.0.3
./configure --prefix=$HOME/domjudge --with-baseurl=127.0.0.1
make judgehost && sudo make install-judgehost
配置 Judgehost
添加用户
useradd -d /nonexistent -U -M -s /bin/false domjudge-run
# 如果 judgehost 拥有多个 CPU 核心,你可以添加额外的用户来支持绑定
# 不同的 judgehost 进程到不同的 CPU 核心上,如下:
useradd -d /nonexistent -U -M -s /bin/false domjudge-run-0
useradd -d /nonexistent -U -M -s /bin/false domjudge-run-1
useradd -d /nonexistent -U -M -s /bin/false domjudge-run-2
useradd -d /nonexistent -U -M -s /bin/false domjudge-run-3
# ... 如果有更多的 CPU 核心,请自行添加更多的用户
配置 sudoers
将 $HOME/domjudge/judgehost/etc/sudoers-domjudge
复制到 /etc/sudoers.d/
目录下。
sudo cp $HOME/domjudge/judgehost/etc/sudoers-domjudge /etc/sudoers.d/
修改 rest 密码
使用 vim 等文本编辑器编辑 ~/domjudge/judgehost/etc/restapi.secret
这个文件。把 DOMserver 中相应文件夹下的对应文件抄一下。
构建 chroot 环境
使用 vim 等文本编辑器编辑 ~/domjudge/judgehost/bin/dj_make_chroot
脚本,将 ubuntu 镜像改为国内源。
(第 172 行)
# Ubuntu mirror, modify to match closest mirror
[ -z "$DEBMIRROR" ] && DEBMIRROR="http://mirrors.aliyun.com/ubuntu/"
提示
因为这一步需要访问网络,若需要配置代理服务器请按需设置。
修改之后保存并运行此脚本。这一步会从源上下载必要的软件包,所以请耐心等待。
设置 cgroup
使用 vim 等文本编辑器编辑 /etc/default/grub
这个文件,对其中的这一行做如下修改:
GRUB_CMDLINE_LINUX_DEFAULT="quiet cgroup_enable=memory swapaccount=1"
然后执行:
update-grub
之后重启计算机。
cat /proc/cmdline
检查是否添加成功。
配置 supervisor
这里针对的是多核判题的配置,单核就没有管理的必要了,直接终端中运行
~/domjudge/judgehost/bin/judgedaemon
即可。
使用 vim 等文本编辑器在 /etc/supervisor/conf.d
下新建一个文本文件叫做 judgehost.conf
,写入下列内容:
[program:judgehost]
command=/home/ubuntu/domjudge/judgehost/bin/judgedaemon -n %(process_num)d
autorestart=true
process_name=%(program_name)s_%(process_num)02d
stdout_logfile=/var/log/judgehost/judgehost.log
stderr_logfile=/var/log/judgehost/judgehost.err.log
numprocs=4
numprocs_start=0
- 上面的 numprocs 应该根据实际的 CPU 核心数。
- 根据实际情况把
ubuntu
改为对应用户名。 - 根据实际情况配置
stdout_logfile
和stderr_logfile
。
最后,使用如下命令重新加载 supervisor :
sudo systemctl restart supervisord.service
- 启动 judgehost
sudo supervisorctl start judgehost
- 查看 judgehost 进程的运行情况:
sudo supervisorctl status
- 每次开机的时候记得执行
~/domjudge/judgehost/bin/create_cgroup
。否则判题的时候会因为权限不够 CE 。
Special Judge
这部分内容应该可以交给出题组来配置。
由于大部分出题人习惯(包括我自己在校赛命题时)使用 Polygon 的 testlib.h 编写 checker,所以此处给出直接将 Polygon 的 checker 搬运至 domjudge 的方法。
由于 domjudge 对于 checker 的入口参数和返回值与传统的 checker 较为不同,所以我们对 testlib.h 进行了修改以使 checker 兼容 domjudge。
内容已删除
提示
此压缩包的配置方式可能过时,现版本的 domjudge 可以不需要添加 build 脚本,直接把 checker.cpp
和 testlib.h
打包即可。具体可以参考此处
。
将使用 Polygon 平台编写的 checker 放入下载的压缩包,并上传至 domjudge 后台。设置对应题目的 Compare script 即可。