Billchenchina 标签 联系 友链

SYZOJ 安装指北

Posted by Billchenchina on May 13, 2018
标签: SYZOJ OnlineJudge

注意

由于目前 SYZOJ2 文档不充分,本文将介绍如何安装 SYZOJ2。

本文写于 2018-5-13,最后更新于 2018-12-09 您阅读本文时 SYZOJ2 安装方式可能已经发生改变,请检查后再阅读本文。

在安装过程中出现问题的时,请加入 LibreOJ 开发群(QQ 群:565280992,Telegram 群:@lojdev

安装 Node.js

SYZOJ2 是基于 Node.js 的 OnlineJudge 网站,所以您需要安装 Node.js。

安装方法见 nodejs.org。(请安装 Node.js 8)

本文给出了 Node.js 在 Ubuntu 16.04 下的安装方式:

curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs

安装 网页端

将 SYZOJ2 网页源码下载到服务器某个目录下:(本文下载到 /var/syzoj

git clone https://github.com/syzoj/syzoj.git /var/syzoj

下载源码后,安装 SYZOJ2 网页端所需依赖:

cd /var/syzoj
npm install

复制默认配置文件并更改配置文件:

cp config-example.json config.json
vim config.json

这里给出了配置文件的具体内容:

{
  "title": "SYZOJ", // 网站名
  "hostname": "127.0.0.1", // 主机地址(如果后续选择使用 nginx 进行反向代理的话保持不变)
  "port": "5283",          // web 端运行端口(如果后续选择使用 nginx 进行反向代理的话可以保持不变)
  "db": { // 数据库配置
    "dialect": "sqlite",   // mysql 或 sqlite
    "database": null,      // mysql 必填
    "username": null,      // mysql 必填
    "password": null,      // mysql 必填
    "host": null,          // mysql 必填
    "storage": "syzoj.db"  // sqlite 必填
  },
  "register_mail": true,   // 见 https://github.com/syzoj/syzoj#邮件配置
  "email": {
    "method": "aliyundm",
    "options": {
      "AccessKeyId": "xxxx",
      "AccessKeySecret": "xxxx",
      "AccountName": "xxxx"
    }
  },
  "upload_dir": "uploads", // 评测数据上传目录
  "default": {             // 默认配置
    "problem": {
      "time_limit": 1000,  // 时间限制
      "memory_limit": 256  // 内存限制
    },
    "user": {
      "show": true,
      "rating": 1500
    }
  },
  "sorting": {
    "ranklist": {
      "field": "rating",
      "order": "desc"
    },
    "problem": {
      "field": "id",
      "order": "asc"
    }
  },
  "limit": {
    "time_limit": 10000,
    "memory_limit": 1024,
    "data_size": 209715200,
    "testdata": 209715200,
    "submit_code": 102400,
    "submit_answer": 10485760,
    "custom_test_input": 20971520,
    "testdata_filecount": 5
  },
  "page": {
    "problem": 50,
    "problem_statistics": 10,
    "judge_state": 10,
    "ranklist": 20,
    "discussion": 10,
    "article_comment": 10,
    "contest": 10,
    "edit_contest_problem_list": 10,
    "edit_problem_tag_list": 10
  },
  "languages": {
    "cpp": {
      "show": "C++",
      "highlight": "cpp",
      "version": "GCC 5.4.0",
      "editor": "c_cpp"
    },
    "cpp11": {
      "show": "C++11",
      "highlight": "cpp",
      "version": "GCC 5.4.0",
      "editor": "c_cpp"
    },
    "csharp": {
      "show": "C#",
      "highlight": "csharp",
      "version": "MCS 4.8.0.0, Mono 4.8.0",
      "editor": "csharp"
    },
    "c": {
      "show": "C",
      "highlight": "c",
      "version": "GCC 5.4.0",
      "editor": "c_cpp"
    },
    "vala": {
      "show": "Vala",
      "highlight": "vala",
      "version": "Vala 0.30.1, GCC 5.4.0",
      "editor": "vala"
    },
    "java": {
      "show": "Java",
      "highlight": "java",
      "version": "GCC 5.4.0",
      "editor": "java"
    },
    "pascal": {
      "show": "Pascal",
      "highlight": "pascal",
      "version": "FPC 3.0.0",
      "editor": "pascal"
    },
    "lua": {
      "show": "Lua",
      "highlight": "lua",
      "version": "Lua 5.2.4",
      "editor": "lua"
    },
    "luajit": {
      "show": "LuaJIT",
      "highlight": "lua",
      "version": "LuaJIT 2.0.4",
      "editor": "lua"
    },
    "python2": {
      "show": "Python 2",
      "highlight": "python",
      "version": "CPython 2.7.12",
      "editor": "python"
    },
    "python3": {
      "show": "Python 3",
      "highlight": "python",
      "version": "CPython 3.5.2",
      "editor": "python"
    },
    "nodejs": {
      "show": "Node.js",
      "highlight": "js",
      "version": "7.7.3",
      "editor": "javascript"
    },
    "ruby": {
      "show": "Ruby",
      "highlight": "ruby",
      "version": "2.3.1",
      "editor": "ruby"
    },
    "haskell": {
      "show": "Haskell",
      "highlight": "haskell",
      "version": "GHC 7.10.3",
      "editor": "haskell"
    },
    "ocaml": {
      "show": "OCaml",
      "highlight": "ocaml",
      "version": "Ocamlbuild 4.02.3",
      "editor": "ocaml"
    },
    "vbnet": {
      "show": "Visual Basic",
      "highlight": "vbnet",
      "version": "VBNC 0.0.0.5943, Mono 4.8.0",
      "editor": "vbscript"
    }
  },
  "links": [ // 友链
    {
      "title": "LibreOJ",
      "url": "https://loj.ac/"
    }
  ],
  "session_secret": "233",                      // session
  "judge_server_addr": "http://127.0.0.1:5284", // 评测机地址
  "judge_token": "233",                         // 评测机 Token
  "email_jwt_secret": "test"                    // email jsonwebtoken secret
}

修改完配置文件后在 /var/syzoj 执行 npm start(默认占用 shell,如果不想占用 shell 的话可以自行使用 screennohup 解决),SYZOJ 即成功运行。

评测机配置

t123yh 的博客 SYZOJ 搭建指南 – t123yh’s Blog 很详细的介绍了 SYZOJ 评测端 judge-v3 的安装方法,本文仅为以上博客的补充。

sandbox-rootfs

除了博客中提到的内容,您还需要下载 sandbox-rootfs.tar.xz

下载后对压缩文件进行解压

tar -xf sandbox-rootfs.tar.xz

并将文件夹放到一个位置(本文以/syzoj-sandbox为例)

mv sandbox-rootfs /syzoj-sandbox

此文件夹的路径将在配置评测机时用到。

评测机配置文件

daemon.json

{
    "RabbitMQUrl": "amqp://localhost/",                              // MQ 地址
    "RedisUrl": "redis://127.0.0.1:6379",                            // Redis 地址
    "TestData": "/var/syzoj/uploads/testdata",                       // 评测数据地址
    "Priority": 1,
    "DataDisplayLimit": 100,
    "TempDirectory": "/tmp"
}

frontend.json

{
    "RabbitMQUrl": "amqp://localhost/",                               // MQ 地址
    "Listen": {
        "host": "127.0.0.1", "port": 5284                             // 评测机地址
    },
    "RemoteUrl": "http://127.0.0.1:5283",                             // SYZOJ 网页端地址
    "Token": "233"                                                    // 评测机 Token(与网页端保持一致)
}

runner-instance.json

{
    "WorkingDirectory": "/mnt/syzoj-tmp1",  // 评测机工作目录
    "SandboxCgroup": "syzoj-1"
}

runner-shared.json

{
    "RabbitMQUrl": "amqp://localhost/",                              // MQ 地址
    "RedisUrl": "redis://127.0.0.1:6379",                            // Redis 地址
    "TestData": "/var/syzoj/uploads/testdata",                       // 评测数据地址
    "Priority": 1,
    "DebugMessageDisplayLimit": 5000,
    "OutputLimit": 104857600,
    "StderrDisplayLimit": 5120,
    "DataDisplayLimit": 128,
    "CompilerMessageLimit": 50000,
    "SpjTimeLimit": 1501,
    "SpjMemoryLimit": 256,
    "SandboxEnvironments": [
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "HOME=/tmp"
    ],
    "SandboxUser": "nobody",
    "SandboxRoot": "/sandbox-rootfs",                           // 见 sandbox-rootfs 节
    "BinaryDirectory": "/tmp/syzoj-runner/work"                     // 一个空的目录即可
}

运行 SYZOJ 评测端

切换到评测机目录(cd /var/syzoj-judge-v3 后需要执行下列命令才能完整运行 SYZOJ 评测端(默认占用 shell,如果不想占用 shell 的话可以自行使用 screennohup 解决):

node lib/daemon/index.js -c /etc/syzoj-config/daemon.json
node lib/frontend-syzoj/index.js -c /etc/syzoj-config/frontend.json
node lib/runner/index.js -s /etc/syzoj-config/shared.json -i /etc/syzoj-config/instance.json

Ref

syzoj/syzoj: An OnlineJudge System for OI

SYZOJ 搭建指南 – t123yh’s Blog

拓展阅读

vincent163 的 SYZOJ2 docker 版 https://github.com/hewenyang/syzoj-docker

SYZOJ 安装信息聚合 https://billchen.bid/syzoj

HeRaNO 在知乎发布的 SYZOJ2 安装指南 https://zhuanlan.zhihu.com/p/44218633