概要
参考文献
- 『Pythonプロフェッショナルプログラミング 第3版』の「Chapter 11 環境構築とデプロイの自動化」
- 『現場で使える Django の教科書《実践編》』の「第7章 デプロイ」
その5:GunicornでDjangoアプリを起動する。
概要
- GunicornでDjangoアプリを起動する。
- Gunicornをsystemdに登録して、
systemctl
で制御できるようにする。
手順
まずは手動でGunicornでDjangoアプリを起動する。
・前提
「appserver」ユーザーで作業する。
$ sudo su appserver $ whoami appserver
・GunicornでDjangoアプリを起動する。
以下の公式ドキュメントによると、manage.py
と同じ階層でgunicorn ${プロジェクト名}.wsgi
を実行すると起動できるとのことである。
docs.djangoproject.com
$ cd /var/application/sources/mysite $ /usr/local/bin/gunicorn mysite.wsgi [2020-05-25 02:50:10 +0000] [22396] [INFO] Starting gunicorn 20.0.4 [2020-05-25 02:50:10 +0000] [22396] [INFO] Listening at: http://127.0.0.1:8000 (22396) [2020-05-25 02:50:10 +0000] [22396] [INFO] Using worker: sync [2020-05-25 02:50:10 +0000] [22399] [INFO] Booting worker with pid: 22399
→ 正常に起動できたように見受けられる。
・確認
以下のように、curlでURLを叩くと302
が返ってきて、プロセスも立ち上がっているので、正常に起動していると判断した。
$ curl -I "http://localhost:8000/admin/" HTTP/1.1 302 Found Server: gunicorn/20.0.4 Date: Mon, 25 May 2020 02:51:06 GMT Connection: close Content-Type: text/html; charset=utf-8 Location: /admin/login/?next=/admin/ Expires: Mon, 25 May 2020 02:51:06 GMT Cache-Control: max-age=0, no-cache, no-store, must-revalidate, private X-Frame-Options: DENY Content-Length: 0 Vary: Cookie X-Content-Type-Options: nosniff $ ps aux | grep "python" | grep -v "grep" appserv+ 22396 0.2 2.3 233980 24160 pts/0 S+ 02:50 0:00 /usr/bin/python3 /usr/local/bin/gunicorn mysite.wsgi appserv+ 22399 0.2 4.0 361756 40520 pts/0 S+ 02:50 0:00 /usr/bin/python3 /usr/local/bin/gunicorn mysite.wsgi $
Gunicornをsystemdに登録する。
・公式ドキュメントは以下
docs.gunicorn.org
・前提
「admin」ユーザーで作業する。
$ whoami admin
・/etc/systemd/system/gunicorn.service
を作成する。
$ cd /etc/systemd/system/ $ sudo touch gunicorn.service
・他のファイルのパーミッションが644
になっているので、合わせておく。
$ ls -l /usr/lib/systemd/system/graphical.target -rw-r--r-- 1 root root 558 2月 3 17:37 /usr/lib/systemd/system/graphical.target $ sudo chmod 644 gunicorn.service $ ls -l gunicorn.service -rw-r--r-- 1 root root 0 5月 25 16:04 gunicorn.service
・gunicorn.service
に以下の内容を設定する。
[gunicorn.service]
[Unit] Description=gunicorn daemon After=network.target [Service] Type=notify PIDFile=/run/gunicorn/pid User=appserver Group=appserver RuntimeDirectory=gunicorn WorkingDirectory=/var/application/sources/mysite ExecStart=/usr/local/bin/gunicorn \ --access-logfile - \ --workers 3 \ --bind=localhost:8000 \ mysite.wsgi ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID KillMode=mixed TimeoutStopSec=5 PrivateTmp=true Restart=always [Install] WantedBy=multi-user.target
・RuntimeDirectory
を作成して所有者を「appserver」ユーザーに設定する。
※ これをやっておかないと、service起動時に「appserver」ユーザーが/run
直下にgunicorn
ディレクトリを作成しようとしてエラーが発生する。
$ sudo mkdir /run/gunicorn $ sudo chown appserver:appserver /run/gunicorn $ ls -ld /run/gunicorn drwxr-xr-x 2 appserver appserver 40 5月 25 20:25 /run/gunicorn
・gunicorn.service
を登録する。
$ sudo systemctl enable gunicorn.service
・gunicornを起動する。
$ sudo systemctl start gunicorn.service
・ステータスを確認する。
$ sudo systemctl status gunicorn.service [sudo] admin のパスワード: ● gunicorn.service - gunicorn daemon Loaded: loaded (/etc/systemd/system/gunicorn.service; enabled; vendor preset: disabled) Active: active (running) since 月 2020-05-25 21:06:37 UTC; 6min ago Main PID: 30331 (gunicorn) Status: "Gunicorn arbiter booted" CGroup: /system.slice/gunicorn.service ├─30331 /usr/bin/python3 /usr/local/bin/gunicorn --access-logfile - --workers 3 --bind=localhost:8000 mysite.wsgi ├─30334 /usr/bin/python3 /usr/local/bin/gunicorn --access-logfile - --workers 3 --bind=localhost:8000 mysite.wsgi ├─30335 /usr/bin/python3 /usr/local/bin/gunicorn --access-logfile - --workers 3 --bind=localhost:8000 mysite.wsgi └─30336 /usr/bin/python3 /usr/local/bin/gunicorn --access-logfile - --workers 3 --bind=localhost:8000 mysite.wsgi 5月 25 21:06:37 ip-172-31-16-161.us-west-2.compute.internal systemd[1]: Starting gunicorn daemon... 5月 25 21:06:37 ip-172-31-16-161.us-west-2.compute.internal gunicorn[30331]: [2020-05-25 21:06:37 +0000] [30331] [INFO] Starting gunicorn 20.0.4 5月 25 21:06:37 ip-172-31-16-161.us-west-2.compute.internal systemd[1]: Started gunicorn daemon. 5月 25 21:06:37 ip-172-31-16-161.us-west-2.compute.internal gunicorn[30331]: [2020-05-25 21:06:37 +0000] [30331] [INFO] Listening at: http://1...0331) 5月 25 21:06:37 ip-172-31-16-161.us-west-2.compute.internal gunicorn[30331]: [2020-05-25 21:06:37 +0000] [30331] [INFO] Using worker: sync 5月 25 21:06:37 ip-172-31-16-161.us-west-2.compute.internal gunicorn[30331]: [2020-05-25 21:06:37 +0000] [30334] [INFO] Booting worker with pid: 30334 5月 25 21:06:37 ip-172-31-16-161.us-west-2.compute.internal gunicorn[30331]: [2020-05-25 21:06:37 +0000] [30335] [INFO] Booting worker with pid: 30335 5月 25 21:06:38 ip-172-31-16-161.us-west-2.compute.internal gunicorn[30331]: [2020-05-25 21:06:38 +0000] [30336] [INFO] Booting worker with pid: 30336 5月 25 21:07:53 ip-172-31-16-161.us-west-2.compute.internal gunicorn[30331]: 127.0.0.1 - - [26/May/2020:06:07:53 +0900] "HEAD /admin/ HTTP/1.1...61.1" Hint: Some lines were ellipsized, use -l to show in full. $
→ 正常に起動できているように見受けられる。
・プロセスを確認する。
$ ps aux | grep "python3" | grep -v "grep" appserv+ 30566 0.0 2.3 236688 24008 ? Ss 21:38 0:00 /usr/bin/python3 /usr/local/bin/gunicorn --access-logfile - --workers 3 --bind=localhost:8000 mysite.wsgi appserv+ 30569 0.0 3.9 361180 39868 ? S 21:38 0:00 /usr/bin/python3 /usr/local/bin/gunicorn --access-logfile - --workers 3 --bind=localhost:8000 mysite.wsgi appserv+ 30570 0.0 3.9 361176 39772 ? S 21:38 0:00 /usr/bin/python3 /usr/local/bin/gunicorn --access-logfile - --workers 3 --bind=localhost:8000 mysite.wsgi appserv+ 30571 0.0 3.9 361176 39772 ? S 21:38 0:00 /usr/bin/python3 /usr/local/bin/gunicorn --access-logfile - --workers 3 --bind=localhost:8000 mysite.wsgi $
→ 意図した通りappserver
ユーザーで起動している。
・curl
で叩いてみる。
$ curl -I "http://localhost:8000/admin/" HTTP/1.1 302 Found Server: gunicorn/20.0.4 Date: Mon, 25 May 2020 21:20:52 GMT Connection: close Content-Type: text/html; charset=utf-8 Location: /admin/login/?next=/admin/ Expires: Mon, 25 May 2020 21:20:52 GMT Cache-Control: max-age=0, no-cache, no-store, must-revalidate, private X-Frame-Options: DENY Content-Length: 0 Vary: Cookie X-Content-Type-Options: nosniff
→ 302
が返ってきたので、正常に起動していると判断した。
・プロセスの親子関係を確認する。
ワーカー数3で起動したところ、プロセスが4つ立ち上がったので、内訳は
- 親プロセス : 1個
- 子プロセス : 3個
かなと思い、ついでに確認してみる。
$ ps auxf | grep "python3" | grep -v "grep" appserv+ 30566 0.0 2.3 236688 24008 ? Ss 21:38 0:00 /usr/bin/python3 /usr/local/bin/gunicorn --access-logfile - --workers 3 --bind=localhost:8000 mysite.wsgi appserv+ 30569 0.0 3.9 361180 39868 ? S 21:38 0:00 \_ /usr/bin/python3 /usr/local/bin/gunicorn --access-logfile - --workers 3 --bind=localhost:8000 mysite.wsgi appserv+ 30570 0.0 3.9 361176 39772 ? S 21:38 0:00 \_ /usr/bin/python3 /usr/local/bin/gunicorn --access-logfile - --workers 3 --bind=localhost:8000 mysite.wsgi appserv+ 30571 0.0 4.0 362092 40504 ? S 21:38 0:00 \_ /usr/bin/python3 /usr/local/bin/gunicorn --access-logfile - --workers 3 --bind=localhost:8000 mysite.wsgi $
→ 予想通りだった。
備忘録
systemdの設定値に関して、まだいくつか意味が理解できていない項目があり、コピペでとりあえず動いた感があるので、後で設定値の意味をちゃんと理解したい。
systemdの仕組みについては、以下のRed Hatの資料にとても詳しく説明されていたので、こちらも後で読みたい。
redhat.lookbookhq.com