0.背景
最近浏览又发现一个新的OJ,HOJ,是基于vue+SpringBoot的,部署用的是Docker,这一点有点像前面我研究的青岛OJ。这篇文章简单记录一下搭建HOJ的过程。
本文环境:
云服务器(CentOS7.5)、宝塔面板、docker、docker-compose、git
PS:按照官方的说法,并不推荐使用CentOS8以下的版本,本文先做一下尝试,如果失败了
1.基于docker的部署
首先要安装docker,具体安装过程可以参考我前面写的文章:
CentOS(宝塔面板)安装docker – 每天进步一点点 (longkui.site)
安装完docker后,参考下面这篇文章安装docker-compose
linux如何安装docker-compose – 每天进步一点点 (longkui.site)
安装这两个完毕后,我们找一个文件夹
执行下面的git命令
git clone https://gitee.com/himitzh0730/hoj-deploy.git && cd hoj-deploy
执行完毕之后,我们可以看到文件夹的目录结构:
docker-compose.yml文件在standAlone文件夹下面,下面贴出默认的配置文件
version: "3"
services:
hoj-redis:
image: redis:5.0.9-alpine
container_name: hoj-redis
restart: always
volumes:
- ${HOJ_DATA_DIRECTORY}/data/redis/data:/data
networks:
hoj-network:
ipv4_address: ${REDIS_HOST:-172.20.0.2}
ports:
- ${REDIS_PORT:-6379}:6379
# --requirepass 后面为redis访问密码
command: redis-server --requirepass ${REDIS_PASSWORD:-hoj123456} --appendonly yes
hoj-mysql:
image: registry.cn-shenzhen.aliyuncs.com/hcode/hoj_database
container_name: hoj-mysql
restart: always
volumes:
- ${HOJ_DATA_DIRECTORY}/data/mysql/data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-hoj123456} # mysql数据库root账号的密码
- TZ=Asia/Shanghai
- NACOS_USERNAME=${NACOS_USERNAME:-root} # 后续nacos所用管理员账号
- NACOS_PASSWORD=${NACOS_PASSWORD:-hoj123456} # 后续nacos所用管理员密码
ports:
- ${MYSQL_PUBLIC_PORT:-3306}:3306
networks:
hoj-network:
ipv4_address: ${MYSQL_HOST:-172.20.0.3}
hoj-nacos:
image: nacos/nacos-server:1.4.2
container_name: hoj-nacos
restart: always
depends_on:
- hoj-mysql
environment:
- JVM_XMX=384m
- JVM_XMS=384m
- JVM_XMN=192m
- MODE=standalone
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=${MYSQL_HOST:-172.20.0.3}
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_USER=root
- MYSQL_SERVICE_PASSWORD=${MYSQL_ROOT_PASSWORD:-hoj123456} # 与上面数据库密码一致
- MYSQL_SERVICE_DB_NAME=nacos
- NACOS_AUTH_ENABLE=true # 开启鉴权
ports:
- ${NACOS_PORT:-8848}:8848
healthcheck:
test: curl -f http://${NACOS_HOST:-172.20.0.4}:8848/nacos/index.html || exit 1
interval: 6s
timeout: 10s
retries: 10
networks:
hoj-network:
ipv4_address: ${NACOS_HOST:-172.20.0.4}
hoj-backend:
image: registry.cn-shenzhen.aliyuncs.com/hcode/hoj_backend
container_name: hoj-backend
restart: always
depends_on:
- hoj-redis
- hoj-mysql
- hoj-nacos
volumes:
- ${HOJ_DATA_DIRECTORY}/file:/hoj/file
- ${HOJ_DATA_DIRECTORY}/testcase:/hoj/testcase
- ${HOJ_DATA_DIRECTORY}/log/backend:/hoj/log/backend
environment:
- TZ=Asia/Shanghai
- JAVA_OPTS=-Xms192m -Xmx384m
- BACKEND_SERVER_PORT=${BACKEND_PORT:-6688}
- NACOS_URL=${NACOS_HOST:-172.20.0.4}:8848
- NACOS_USERNAME=${NACOS_USERNAME:-root} # 登录 http://ip:8848/nacos 分布式配置中心与注册中心的后台的账号
- NACOS_PASSWORD=${NACOS_PASSWORD:-hoj123456} # 密码
- JWT_TOKEN_SECRET=${JWT_TOKEN_SECRET:-default} # token加密秘钥 默认则生成32位随机密钥
- JWT_TOKEN_EXPIRE=${JWT_TOKEN_EXPIRE:-86400} # token过期时间默认为24小时 86400s
- JWT_TOKEN_FRESH_EXPIRE=${JWT_TOKEN_FRESH_EXPIRE:-43200} # token默认12小时可自动刷新
- JUDGE_TOKEN=${JUDGE_TOKEN:-default} # 调用判题服务器的token 默认则生成32位随机密钥
- MYSQL_HOST=${MYSQL_HOST:-172.20.0.3}
- MYSQL_PUBLIC_HOST=${MYSQL_PUBLIC_HOST:-172.20.0.3} # 如果判题服务是分布式,请提供当前mysql所在服务器的公网ip
- MYSQL_PUBLIC_PORT=${MYSQL_PUBLIC_PORT:-3306}
- MYSQL_PORT=3306
- MYSQL_DATABASE_NAME=hoj # 改动需要修改hoj-mysql镜像,默认为hoj
- MYSQL_USERNAME=root
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-hoj123456}
- EMAIL_SERVER_HOST=${EMAIL_SERVER_HOST:-smtp.qq.com} # 请使用邮件服务的域名或ip
- EMAIL_SERVER_PORT=${EMAIL_SERVER_PORT:-465} # 请使用邮件服务的端口号
- EMAIL_USERNAME=${EMAIL_USERNAME:-your_email_username} # 请使用对应邮箱账号
- EMAIL_PASSWORD=${EMAIL_PASSWORD:-your_email_password} # 请使用对应邮箱密码
- REDIS_HOST=${REDIS_HOST:-172.20.0.2}
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD:-hoj123456}
- OPEN_REMOTE_JUDGE=true # 是否开启各个remote judge
# 开启虚拟判题请提供对应oj的账号密码 格式为
# username1,username2,...
# password1,password2,...
- HDU_ACCOUNT_USERNAME_LIST=${HDU_ACCOUNT_USERNAME_LIST}
- HDU_ACCOUNT_PASSWORD_LIST=${HDU_ACCOUNT_PASSWORD_LIST}
- CF_ACCOUNT_USERNAME_LIST=${CF_ACCOUNT_USERNAME_LIST}
- CF_ACCOUNT_PASSWORD_LIST=${CF_ACCOUNT_PASSWORD_LIST}
- POJ_ACCOUNT_USERNAME_LIST=${POJ_ACCOUNT_USERNAME_LIST}
- POJ_ACCOUNT_PASSWORD_LIST=${POJ_ACCOUNT_PASSWORD_LIST}
- ATCODER_ACCOUNT_USERNAME_LIST=${ATCODER_ACCOUNT_USERNAME_LIST}
- ATCODER_ACCOUNT_PASSWORD_LIST=${ATCODER_ACCOUNT_PASSWORD_LIST}
- SPOJ_ACCOUNT_USERNAME_LIST=${SPOJ_ACCOUNT_USERNAME_LIST}
- SPOJ_ACCOUNT_PASSWORD_LIST=${SPOJ_ACCOUNT_PASSWORD_LIST}
# 是否强制使用配置文件的remote judge账号覆盖原有系统的账号列表
- FORCED_UPDATE_REMOTE_JUDGE_ACCOUNT=${FORCED_UPDATE_REMOTE_JUDGE_ACCOUNT:-false}
ports:
- ${BACKEND_PORT:-6688}:${BACKEND_PORT:-6688}
networks:
hoj-network:
ipv4_address: ${BACKEND_HOST:-172.20.0.5}
hoj-frontend:
image: registry.cn-shenzhen.aliyuncs.com/hcode/hoj_frontend
container_name: hoj-frontend
restart: always
# 开启https,请提供证书
#volumes:
# - ./server.crt:/etc/nginx/etc/crt/server.crt
# - ./server.key:/etc/nginx/etc/crt/server.key
# 修改前端logo
# - ./logo.a0924d7d.png:/usr/share/nginx/html/assets/img/logo.a0924d7d.png
# - ./backstage.8bce8c6e.png:/usr/share/nginx/html/assets/img/backstage.8bce8c6e.png
environment:
- SERVER_NAME=localhost # # 域名或localhost(本地)
- BACKEND_SERVER_HOST=${BACKEND_HOST:-172.20.0.5} # backend后端服务地址
- BACKEND_SERVER_PORT=${BACKEND_PORT:-6688} # backend后端服务端口号
- USE_HTTPS=false # 使用https请设置为true
ports:
- "80:80"
- "443:443"
networks:
hoj-network:
ipv4_address: 172.20.0.6
hoj-judgeserver:
image: registry.cn-shenzhen.aliyuncs.com/hcode/hoj_judgeserver
container_name: hoj-judgeserver
restart: always
depends_on:
- hoj-mysql
- hoj-nacos
volumes:
- ${HOJ_DATA_DIRECTORY}/testcase:/judge/test_case
- ${HOJ_DATA_DIRECTORY}/judge/log:/judge/log
- ${HOJ_DATA_DIRECTORY}/judge/run:/judge/run
- ${HOJ_DATA_DIRECTORY}/judge/spj:/judge/spj
- ${HOJ_DATA_DIRECTORY}/judge/interactive:/judge/interactive
- ${HOJ_DATA_DIRECTORY}/log/judgeserver:/judge/log/judgeserver
environment:
- TZ=Asia/Shanghai
- JAVA_OPTS=-Xms192m -Xmx384m # 修正JVM参数以便适应单机部署
- JUDGE_SERVER_IP=${JUDGE_SERVER_IP:-172.20.0.7}
- JUDGE_SERVER_PORT=${JUDGE_SERVER_PORT:-8088}
- JUDGE_SERVER_NAME=${JUDGE_SERVER_NAME:-judger-alone} # 判题服务的名字
- NACOS_URL=${NACOS_HOST:-172.20.0.4}:8848
- NACOS_USERNAME=${NACOS_USERNAME:-root}
- NACOS_PASSWORD=${NACOS_PASSWORD:-hoj123456}
- MAX_TASK_NUM=${MAX_TASK_NUM:--1} # -1表示最大可接收判题任务数为cpu核心数+1
- REMOTE_JUDGE_OPEN=${REMOTE_JUDGE_OPEN:-true} # 当前判题服务器是否开启远程虚拟判题功能
- REMOTE_JUDGE_MAX_TASK_NUM=${REMOTE_JUDGE_MAX_TASK_NUM:--1} # -1表示最大可接收远程判题任务数为cpu核心数*2+1
- PARALLEL_TASK=${PARALLEL_TASK:-default} # 默认沙盒并行判题程序数为cpu核心数
ports:
- ${JUDGE_SERVER_PORT:-8088}:${JUDGE_SERVER_PORT:-8088}
# - "0.0.0.0:5050:5050" # 一般不开放安全沙盒端口
healthcheck:
test: curl -f http://${JUDGE_SERVER_IP:-172.20.0.7}:${JUDGE_SERVER_PORT:-8088}/version || exit 1
interval: 30s
timeout: 10s
retries: 3
privileged: true # 设置容器的权限为root
shm_size: 512mb
networks:
hoj-network:
ipv4_address: 172.20.0.7
hoj-mysql-checker:
image: registry.cn-shenzhen.aliyuncs.com/hcode/hoj_database_checker
container_name: hoj-mysql-checker
depends_on:
- hoj-mysql
links:
- hoj-mysql:mysql
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-hoj123456}
networks:
hoj-network:
ipv4_address: 172.20.0.8
hoj-autohealth: # 监控不健康的容器进行重启
restart: always
container_name: hoj-autohealth
image: willfarrell/autoheal
environment:
- AUTOHEAL_CONTAINER_LABEL=all
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
hoj-network:
driver: bridge
ipam:
config:
- subnet: ${SUBNET:-172.20.0.0/16}
建议大家把默认的密码改一下,当然,不改也可以运行。
然后,我们在standAlone文件下面执行指令。
docker-compose up -d
注:经过测试发现,用宝塔自带的终端执行docker-compose up -d 容易丢失连接,所以这一步建议用第三方工具来执行上面的命令。
执行完毕后,下载下来的镜像如下:
然后,我们查看一下容器的状态:
容器没有正常启动的原因一般是端口被占用了,比如我这里,已经有一个网站和mysql了,所以80端口和3306端口已经被占用了,本文为了测试,所以先把外层的nginx(apache)和mysql,再启动容器。
如果要不影响原来的程序并成功启动docker,想要修改端口,请参考下面这篇文章,
centos(宝塔)搭建HOJ(2)—依赖关系和修改端口 – 每天进步一点点 (longkui.site)
然后,访问你服务器的IP,就能看到下面的界面了:
第一步大功告成了。