Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add docker support #136

Merged
merged 3 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/judge/data
/polygon/data
50 changes: 50 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# 使用php7.4-fpm-alpine作为基础镜像
FROM php:7.4-fpm-alpine

# 设置apk源为国内镜像源,并安装tzdata和curl
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories \
&& apk add --no-cache tzdata curl build-base

# 设置时区为Asia/Shanghai
ENV TZ "Asia/Shanghai"
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone

# 添加用户
RUN addgroup -g 1000 -S www && adduser -s /sbin/nologin -S -D -u 1000 -G www www

ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

# 安装php扩展
RUN chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions gd imagick opcache pdo_mysql mysqli pcntl zip

# 安装Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# 设置Composer镜像源
RUN composer config -g repos.packagist composer https://packagist.mirrors.sjtug.sjtu.edu.cn

# 设置工作目录
WORKDIR /var/composer

# 将composer.json和composer.lock复制到工作目录
COPY composer.json .
COPY composer.lock .
COPY patches ./patches

# 安装项目依赖
RUN composer install

# 拷贝配置文件
COPY /conf.d/www.conf /usr/local/etc/php-fpm.d/www.conf

RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
RUN sed -i 's/^upload_max_filesize = .*/upload_max_filesize = 100M/' "$PHP_INI_DIR/php.ini" \
&& sed -i 's/^post_max_size = .*/post_max_size = 200M/' "$PHP_INI_DIR/php.ini"

RUN mkdir -p /var/log/php-fpm
RUN ln -sf /dev/stdout /var/log/php-fpm/error.log

WORKDIR /var/www/html
CMD ["sh", "-c","cp -fr /var/composer/vendor /var/www/html && php-fpm"]
35 changes: 35 additions & 0 deletions Dockerfile.judge.alpine
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# 使用alpine作为基础镜像
FROM alpine:3.18

ENV LANG C.UTF-8

# 设置apk源为国内镜像源
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories

ENV TZ "Asia/Shanghai"

RUN apk add --no-cache tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& apk add --no-cache python3-dev openjdk17 build-base mariadb-dev mariadb-connector-c-dev openssl libseccomp \
&& ln -sf python3 /usr/bin/python \
&& rm -rf /var/cache/apk/*

WORKDIR /build
COPY judge judge
COPY polygon polygon

WORKDIR /build/judge
RUN make \
&& chmod +x dispatcher

WORKDIR /build/polygon
RUN make \
&& chmod +x polygon

# 新建judge用户
RUN adduser -D -u 1536 judge

WORKDIR /judge
USER root
CMD ["sh", "-c","cp -f /build/judge/dispatcher /judge/judge/dispatcher && cp -f /build/judge/judge /judge/judge/judge && cp -f /build/polygon/polygon /judge/polygon/polygon && cp -f /build/polygon/judge /judge/polygon/judge && ./judge/dispatcher && ./polygon/polygon && tail -f /dev/null"]
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ SCNUOJ 可对用户在线提交的源代码进行编译和执行,并通过预

如有任何问题,可新建 Issue。

- [安装指引](./docs/installation.md) - 部署 SCNUOJ 到你的设备上
- [普通安装指引](./docs/installation.md) - 部署 SCNUOJ 到你的设备上
- [Docker 安装指引](./docs/docker.md) - 使用 Docker 部署 SCNUOJ
- [升级指引](./docs/upgrade.md) - 从 JNOJ 或旧版本的 SCNUOJ 升级
- [二次开发指引](./docs/development.md) - 在 SCNUOJ 的基础上迭代出自己的 OJ

Expand Down
19 changes: 19 additions & 0 deletions conf.d/Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
:80 {
root * /var/www/html/web
encode gzip

@disallowed {
path /index_test.php
}

try_files {path} {path}/ /index.php?{query}
rewrite @disallowed /index.php

php_fastcgi php:9000 {
root /var/www/html/web
}

file_server {
index index.html
}
}
1 change: 1 addition & 0 deletions conf.d/init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE DATABASE IF NOT EXISTS scnuoj;
14 changes: 14 additions & 0 deletions conf.d/www.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[www]
user = www
group = www
listen = 0.0.0.0:9000
pm = dynamic
pm.max_children = 8
pm.start_servers = 4
pm.min_spare_servers = 1
pm.max_spare_servers = 7
pm.max_requests = 512

catch_workers_output = yes
php_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php-fpm/error.log
60 changes: 43 additions & 17 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
# Taken from https://github.com/shi-yang/jnoj/commit/1377a504e4542ddccaa85301c1eece13e2e4fab8
# Thanks @shi-yang

# This file is for development propose only.
# You will have to adjust config/db.php to use the correct host (mysql) and user (root).

version: '3'
version: "3"

services:
myadminfortest:
image: phpmyadmin/phpmyadmin
container_name: myadminfortest
container_name: myadmin
ports:
- 8888:80
environment:
UPLOAD_LIMIT: 512M
MEMORY_LIMIT: 1024M
depends_on:
- mysql
environment:
PMA_USER: root
PMA_PASSWORD: 123456
links:
- mysql:db

Expand All @@ -26,14 +20,46 @@ services:
restart: always
volumes:
- ./data/mysql/data:/var/lib/mysql
- ./conf.d/init.sql:/docker-entrypoint-initdb.d/init.sql
environment:
MYSQL_DATABASE: scnuoj
MYSQL_ROOT_PASSWORD: 123456
MYSQL_ROOT_PASSWORD: yourpassword
TZ: Asia/Shanghai

caddy:
image: caddy:latest
container_name: caddy
ports:
- 80:80
- 443:443
volumes:
- ./conf.d/Caddyfile:/etc/caddy/Caddyfile
- ./:/var/www/html
environment:
- TZ=Asia/Shanghai
depends_on:
- php

php:
image: yiisoftware/yii2-php:7.4-apache
container_name: php
build:
context: .
dockerfile: Dockerfile
volumes:
- ./:/app:delegated
ports:
- '8000:80'
- ./:/var/www/html
# ports:
# - "9000:9000"
depends_on:
- mysql

judge:
container_name: judge
build:
context: .
dockerfile: Dockerfile.judge.alpine
volumes:
- ./judge:/judge/judge
- ./polygon:/judge/polygon
depends_on:
- mysql
- php
- caddy
113 changes: 113 additions & 0 deletions docs/docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# 使用 Docker 部署 `scnuoj`

众所周知,`scnuoj` 性能垃圾,支持的功能少还难以配置。但是没办法,生活还是要继续,性能和功能想解决还得费点时间。那就先解决难以配置的问题吧。

## 1. 环境配置

### 1.1 安装 Git

```shell
#debian/ubuntu
sudo apt install git -y
#centos/rehl
sudo yum install git -y
```

### 1.2 安装 Docker

请参考[这篇教程](https://mirrors.tuna.tsinghua.edu.cn/help/docker-ce/)。

### 1.3 安装 docker-compose

```shell
#debian/ubuntu
sudo apt install docker-compose -y
#centos/rehl
sudo yum install docker-compose -y
```

至此,环境配置已经完成

## 2. 获取并修改源码

### 2.1 获取源码

```shell
git clone https://github.com/scnu-socoding/scnuoj.git
```

### 2.2 修改数据库信息

#### 2.2.1 修改 `/docker-compose.yaml`

将 `MYSQL_ROOT_PASSWORD` 的值更改为你想要的密码

#### 2.2.2 修改 `/config/db.php`

将 `dsn` 修改为 `mysql:host=mysql;dbname=scnuoj`

将 `username` 修改为 `root`

`password` 修改为 你刚才设置的密码

#### 2.2.3 修改 `/judge/src/judge.c`

将 `use_ptrace` 的值修改为 `0`

> Tips: 这里修改的原因是 P trace 机制和 Docker 存在兼容性问题导致。Docker 里的 system call 的值貌似不固定(?)

#### 2.2.4 修改 `/polygon/src/judge.c`

同上

#### 2.2.5 修改 `/conf.d/Caddyfile`

详情请根据 Caddy 官方文档。

## 3. 安装

首次运行需要安装 `scnuoj` 。

先在 `/scnuoj` 目录下运行:

```shell
docker-compose up -d --build
```

生成镜像需要时间,请耐心等待打包完成。

运行成功后,进入 `php` 容器。

首先,先使用 `docker container ls` 命令获取 `php` 容器的 `CONTAINER ID`。

然后,输入 `docker exec -it 刚才获取的ID sh` 进入容器。

运行 `./yii install` 进行安装。根据提示输入管理员账号、密码和邮箱即可。

> 如果提示权限不足则先执行 `chmod +x yii` 。

输入 `exit` 退出容器。此时 `scnuoj` 已经搭建完成。

输入:

```shell
docker-compose down; docker-compose up -d
```

重启容器,即可提供服务。

## 迁移

容器化最大的好处就是迁移的时候十分方便。迁移时只需要输入 `docker-compose down` 在源服务器上停止服务。将整个文件夹打包迁移到新服务器上,重复第一步的环境配置,即可通过 `docker-compose up -d` 一键开启服务。

## 判题机开启 oi 模式

进入判题机容器,kill 掉原有的判题机进程,然后输入

```shell
./judge/dispatcher -o
./polygon/polygon -o

```

即可开启 oi 模式。如需关闭,重启容器即可。
8 changes: 4 additions & 4 deletions models/Solution.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,10 +276,10 @@ public static function getLanguageList($status = '')
{
$arr = [
'' => '请选择',
'0' => 'C (GCC 9.3.0)',
'1' => 'C++ (GCC 9.3.0)',
'2' => 'Java (OpenJDK 11.0.11)',
'3' => 'Python (3.8.10)'
'0' => 'C (GCC 12.2.1)',
'1' => 'C++ (GCC 12.2.1)',
'2' => 'Java (OpenJDK 17.0.9)',
'3' => 'Python (3.11.6)'
];
return $status === '' ? $arr : $arr[$status];
}
Expand Down
8 changes: 4 additions & 4 deletions views/wiki/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,25 +93,25 @@

<div class="list-group">
<div class="list-group-item">
<b>C</b> (GCC 9.3.0)<br>
<b>C</b> (GCC 12.2.1)<br>
<small>
<code>gcc Main.c -o Main -fno-asm -O2 -Wall -lm --static -std=c11 -DONLINE_JUDGE</code>
</small>
</div>
<div class="list-group-item">
<b>C++</b> (GCC 9.3.0)<br>
<b>C++</b> (GCC 12.2.1)<br>
<small>
<code>g++ -fno-asm -O2 -Wall -lm --static -std=c++14 -DONLINE_JUDGE -o Main Main.cc</code>
</small>
</div>
<div class="list-group-item">
<b>Java</b> (OpenJDK 11.0.11)<br>
<b>Java</b> (OpenJDK 17.0.9)<br>
<small>
<code>javac -J-Xms32m -J-Xmx256m Main.java</code>
</small>
</div>
<div class="list-group-item">
<b>Python</b> (3.8.5)<br>
<b>Python</b> (3.11.6)<br>
<small>
编译参数不可用。
</small>
Expand Down
Loading