在Ubuntu建立已運作解題ZSOJ的備份系統
實作DMOJ(版本2.1.0)網站(http://203.68.236.9/)的備份系統
需要備份原來伺服器的資料夾site與資料庫,下方粗體字部分。
系統與Python版本如下
Ubuntu 20.04.1 LTS
Python 3.8
node v16.17.1
(一)安裝DMOJ
Step1)安裝必要套件
$ sudo apt update
$ sudo apt install git gcc g++ make python3-dev python3-pip libxml2-dev libxslt1-dev zlib1g-dev gettext curl redis-server
$ sudo curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
$ sudo apt install nodejs
$ sudo npm install -g sass postcss-cli postcss autoprefixer
Step2)安裝Mysql資料庫
$ sudo apt install mariadb-server libmysqlclient-dev
設定Mysql資料庫,預設root密碼為空白,直接按下Enter,資料庫帳號為dmoj,需修改<password>為資料庫密碼。
$ mysql -uroot -p
mariadb> CREATE DATABASE dmoj DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;
mariadb> GRANT ALL PRIVILEGES ON dmoj.* to 'dmoj'@'localhost' IDENTIFIED BY '<password>';
mariadb> exit
Step3)建立與啟動Python3的虛擬環境
$ sudo apt install python3-venv
以下指令可以使用登入使用者權限進行安裝,建立在該使用者的家目錄下
$ python3 -m venv dmojsite
$ . dmojsite/bin/activate
Step4)下載程式與資源檔案
使用tar壓縮ZSOJ伺服器上的DMOJ資料夾site,並透過網路傳送到新機器。
(dmojsite) $ cd site
(dmojsite) $ git submodule init
(dmojsite) $ git submodule update
Step5)安裝python所需模組
在ZSOJ伺服器上使用指令「(dmojsite) $ pip freeze > requirements-zsoj.txt」可以備份目前所有套件的版本。
(dmojsite) $ pip3 install -r requirements-zsoj.txt #安裝所需python套件
若安裝過程出現錯誤,則
(1)可以使用#去除安裝錯誤的套件,之後再補安裝。
(2)或者去除版本號碼,可能該版本已經無法使用。
(3)有時個別安裝可以,全部一起安裝無法安裝,例如dmoj與termcolor套件,最後獨立安裝dmoj即可。
錯誤1:如果出現錯誤 「git clone -q git://github.com/dmoj/django-sortedm2m.git fatal: unable to connect to github.com」
在命令模式執行「git config --global url."https://".insteadOf git://」,使用https://取代git://。
錯誤2:如果出現錯誤「error: invalid command ‘bdist_wheel」
#pip install wheel
#pip install pyinstaller
錯誤3:如果出現錯誤「fatal error: seccomp.h: No such file or directory」
#sudo apt install libseccomp-dev
(dmojsite) $ pip3 install -r requirements-zsoj.txt --force #安裝所需python套件,未完整安裝,後方套件補裝
(dmojsite) $ pip3 install mysqlclient ansi2html martor lupa webauthn netaddr
Step6)在dmoj資料夾下新增local_settings.py,下載自https://github.com/DMOJ/docs/blob/master/sample_files/local_settings.py,進行修改,如下,DMOJ的local_settings.py。
檢查dmoj目前是否還正常
(dmojsite) $ python3 manage.py check
錯誤1:如果出現錯誤「cannot import name '...' from 'jinja2'」
安裝django-jinja、markupsafe與Jinja2, 「pip install pip install django-jinja==2.7.0」「pip install markupsafe==2.0.1」「pip install Jinja2==2.11.3」
錯誤2:如果出現錯誤「No module named 'sortedm2m'」
安裝django-sortedm2m,「pip install django-sortedm2m」
Step7)收集static資料夾內檔案,static資料夾定義在local_settings.py的「STATIC_ROOT = '/home/jang/site/static/'」,所以建立資料夾/home/jang/site/static
(dmojsite) $ mkdir /home/jang/site/static
(dmojsite) $ cd /home/jang/site
(dmojsite) $ ./make_style.sh
錯誤1:出現「ReferenceError: globalThis is not defined」重新安裝nodejs。
$ sudo curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
$ sudo apt install nodejs
$ sudo npm install -g sass postcss-cli postcss autoprefixer
錯誤2:出現以下錯誤unexpected token '.',表示node版本有相容性問題。
安裝node版本控制套件n
$sudo npm install -g n
下載穩定版本的node,筆者安裝node20.11.1版(2024/03/23測試)
$sudo n lts
再重新執行「./make_style.sh」
在site資料夾下,重新命名static為static2,並重新建立空資料夾static,執行以下指令將檔案放置於資料夾static。
(dmojsite) $ python3 manage.py collectstatic
如果出現「AttributeError: module 'mistune' has no attribute '_pre_tags'」,安裝mistune0.8.0
#pip install mistune==0.8.0
Step8)建立語言檔
(dmojsite) $ python3 manage.py compilemessages
(dmojsite) $ python3 manage.py compilejsi18n
Step9)建立資料庫內的資料表,與備份還原資料庫
(dmojsite) $ python3 manage.py migrate
使用指令「mysqldump -u root -p dmoj > zsoj.sql」備份ZSOJ上的資料庫dmoj
使用指令「mysql -u root -p dmoj < zsoj.sql」還原到新機器的資料庫dmoj
Step10)載入安裝資料
(dmojsite) $ python3 manage.py loaddata navbar
(dmojsite) $ python3 manage.py loaddata language_small
(dmojsite) $ python3 manage.py loaddata demo
Step11)啟用DMOJ
在新機器的dmoj/settings.py的ALLOWED_HOSTS新增主機IP,如右,ALLOWED_HOSTS = ['新機器IP']
(dmojsite) $ python3 manage.py runserver 0.0.0.0:8000
使用瀏覽器瀏覽http://新機器IP:8000/,正常情況應該可以看到DMOJ
不要使用runserver啟用dmoj,改用nginx與uWSGI
Step12)啟用Bridge,沒出現錯誤就Ctrl+C
(dmojsite) $ python3 manage.py runbridged
如果出現錯誤「OSError: [Errno 99] Cannot assign requested address」表示site/dmoj/local_settings.py的BRIDGED_JUDGE_ADDRESS設定錯誤。
Step13)啟用redis與celery,celery是分散式任務處理系統,將需要長時間處理的程式交給其他機器處理,而redis是celery的broker(中間人)與backend(結果儲存)
(dmojsite) $ sudo service redis-server start
在local_settings.py取消註解CELERY_BROKER_URL與CELERY_RESULT_BACKEND
(dmojsite) $ pip3 install redis
在site資料夾下有dmoj_celery.py,在site資料夾下執行以下指令
(dmojsite) $ celery -A dmoj_celery worker
Step14)設定uWSGI
編輯設定檔uwsgi.ini,如下,檢查是否要修改資料夾路徑
(dmojsite) $ pip3 install uwsgi
(dmojsite) jian@jian:~/site$ uwsgi --ini uwsgi.ini
出現spawned表示正常,使用Ctrl+C中斷
Step15)使用supervisor啟動uwsgi、bridged、celery
(dmojsite) $ sudo apt install supervisor
在/etc/supervisor/conf.d/下建立設定檔site.conf、bridged.conf與celery.conf
site.conf如下,檢查是否要修改資料夾路徑
bridged.conf如下,檢查是否要修改資料夾路徑
celery.conf如下,檢查是否要修改資料夾路徑
使用supervisor啟用uwsgi、bridged、celery,等一下nginx會呼叫使用
(dmojsite)$ sudo supervisorctl update
(dmojsite)$ sudo supervisorctl status
Step16)安裝與設定nginx,使用nginx當成web伺服器,呼叫後方的uwsgi,uwsgi再呼叫django的dmoj套件
(dmojsite) $ sudo apt install nginx
編輯設定檔/etc/nginx/site-available/default,檢查是否要修改server_name與資料夾路徑
建立超連結sites-enabled/default指向sites-available/default
$ sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
測試nginx
$sudo nginx -t
啟動nginx
$service nginx start
使用瀏覽器瀏覽http://192.168.43.16:8080就可以看到nginx所啟動的DMOJ
如果出現錯誤「Bad Request (400) 」,編輯「site/dmoj/local_setting.py」,在ALLOWED_HOSTS 加入伺服器的IP
Step17)設定event server,新增/home/jang/site/websocket/config.js如下,在local_settings.py的EVENT_DAEMON_POST、EVENT_DAEMON_GET與EVENT_DAEMON_POLL也需設定,在前面local_settings.py中已經加上。
檢查是否需要在websocket/config.js加上以下資料,已經有了就不加。
(dmojsite) $ cat > websocket/config.js
module.exports = {
get_host: '127.0.0.1',
get_port: 15100,
post_host: '127.0.0.1',
post_port: 15101,
http_host: '127.0.0.1',
http_port: 15102,
long_poll_timeout: 29000,
};
安裝套件
(dmojsite) $ npm install qu ws simplesets
(dmojsite) $ pip install websocket-client
在supervisor啟動event server
編輯/etc/supervisor/conf.d/wsevent.conf,如下,檢查是否要修改server_name與資料夾路徑。
Step19)重新啟動服務
$ sudo supervisorctl update
$ sudo supervisorctl restart bridged
$ sudo supervisorctl restart site
$ sudo service nginx restart
Step20)重新建立judge server
請參考「在Ubuntu安裝DMOJ Judge Server」
Step21)修改網站的名稱與IP、連接埠的對應
使用管理者登入DMOJ,點選「Dashboard->網站」編輯網站對應的IP、連接埠
參考資料