VisualSdudioで開発していたDjango3.2のプロジェクトを、CentOSサーバーに公開する手順についてのメモ書き。
デプロイに関する3.2のドキュメントは以下。
https://docs.djangoproject.com/ja/3.2/howto/deployment/
今回は最終的にuWSGIでサーバーを構築する予定で、設定の流れは以下が参考になる。
https://uwsgi.readthedocs.io/en/latest/tutorials/Django_and_nginx.html
流れとしては、以下の順に順次確認して最終形にする。
- Django
- uWSGI –> Django
- nginx –> uWSGI –> Django
- WAF –> nginx –> uWSGI –> Django
まずはDjangoプロジェクトを設定して単体で確認する。
0.今回の条件
- クライアント開発環境:Visual Studio Community 2022
- Djangoバージョン:3.2
- サーバー:CentOS Stream9
- WAF:nginx+Naxsiサーバー
- ソース管理:自前Gitサーバー
1.Djangoプロジェクト構築
1-1. Python
サーバーにインストールされているpythonのバージョンを確認。
python --version
今回のサーバーは3.9で、クライアント開発時と同じのためそのまま使うことにし、pyenvは使わないこととした
1-2. pip,git
dnf install pip
dnf install git
1-3. アプリ実行ユーザー作成
Django実行用のアプリユーザー(仮にappユーザー)を作成し、ユーザー変更する。
adduser app
su - app
1-4. Gitクライアント設定
gitサーバーは同じセグメント内の別サーバーにあり、鍵認証としている。
1)appユーザーで、鍵を作成する。
ssh-keygen -t rsa -b 4096
2)作成した公開鍵を、Gitサーバーに登録
作成された公開鍵(~/.ssh/id_rsa.pub)を、Gitサーバーのgitユーザーのauthorized_keysに登録する。
1-5. Djangoソース取得
Djangoプロジェクト用のディレクトリを作成(仮に~/django)して移動して、gitからソースを取得(クローン)する。
git clone ssh://git@10.10.10.1:9999/~/myapp.git
1-6. python実行環境
プロジェクトフォルダ配下に環境を構築し、必要なパッケージをインストール。
cd myapp
virtualenv env
cd env
source bin/activate
pip install -r ../requirements.txt
appユーザーの.bash_profileにvirtualenvのactivateを仕込んでおく。
1-7. Djangoの設定
設定をサーバー用に修正して、デプロイチェック。
https://docs.djangoproject.com/ja/3.2/howto/deployment/checklist/
まずはDEBUG=Flaseとする。SSL周りの設定については、WAFからの呼び出しのため後に設定。
ログファイルのディレクトリとしては以下を作成する。
mkdir /var/log/django
chown app:app /var/log/django
データベースについて、新規に作成した場合は、マイグレーションとスーパーユーザーを作成する。
https://docs.djangoproject.com/en/3.2/topics/migrations/
1-8. Django単体の確認
Django開発サーバーを立ち上げて、起動できることを確認する。
python manage.py runserver 0.0.0.0:8000
ブラウザで確認すると、DEBUG=Flaseとしているためstatic以下が取得できないが、この時点では無視して、後でnginx設定時に対応する。
2.uWSGI構築
2-1. uWSGIインストール
https://uwsgi.readthedocs.io/en/latest/Install.html
dnf groupinstall "Development Tools"
dnf install python-devel
pip install uwsgi
2-2. uWSGI設定
https://docs.djangoproject.com/ja/3.2/howto/deployment/wsgi/uwsgi/
起動用のuwsgi.iniファイルを/home/app/django/myapp/に作成する。設定例は以下。
[uwsgi]
chdir=/home/app/django/myapp/
module=myapp.wsgi:application
master=True
pidfile=/tmp/myapp-master.pid
vacuum=True
max-requests=5000
daemonize=/var/log/uwsgi/daemon-@(exec://date +%%Y-%%m-%%d).log
http-socket = :8000
#socket=/usr/share/nginx/tmp/uwsgi.sock ※nginxとunixソケットでつなぐ場合
/var/log/uwsgiは以下で作成
mkdir /var/log/uwsgi
chown app:app /var/log/uwsgi
パラメータに関するドキュメントは以下。
https://uwsgi.readthedocs.io/en/latest/Options.html
2-3. 起動コマンド
uWSGIの起動コマンドstart_uwsgi.shを、/home/app/django/myapp/binに作成する。
#!/bin/sh
cd /home/app/django/myapp/
source env/bin/activate
env/bin/uwsgi --ini uwsgi.ini
起動コマンドに実行権を付与して実行し、正常に動作することを確認する。
2-4. uwsgiサービス登録
/usr/lib/systemd/systemに、サービス定義ファイルuwsgi.serviceを作成する。
[Unit]
Description=UWSGI
After=network-online.target
Wants=network-online.target
[Service]
Type=forking
ExecStart=/home/app/django/myapp/bin/start_uwsgi.sh
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=mixed
User=app
Group=app
[Install]
WantedBy=multi-user.target
定義ファイルを作成したら、サービスの起動設定を行う。
systemctl enable uwsgi.service
systemctl start uwsgi.service
3.nginx構築
3.1 nginxインストール
dnf install nginx
3.2 static設定
https://docs.djangoproject.com/en/3.2/howto/static-files/#deployment
1)ディレクトリ作成
staticファイル配置用のディレクトリを作成する。nginxから参照できる場所として以下とし、appユーザーからもアクセスできるようにする。
mkdir /usr/share/nginx/static
chmod 777 /usr/share/nginx/static
2)Django設定
Djangoプロジェクトのsetting.pyのSTATIC_ROOTに、上記ディレクトリを設定
STATIC_ROOT = '/usr/share/nginx/static/'
3)ファイル配置
appユーザーにて以下を実行する。
python manage.py collectstatic
3.3 設定
https://uwsgi.readthedocs.io/en/latest/Nginx.html
nginxの設定ファイルに以下を追加。
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
#uwsgi_pass unix:/usr/share/nginx/tmp/uwsgi.sock; ※unixソケットの場合
}
location /static {
alias /usr/share/nginx/static;
}
※unixソケットを使う場合はこちらを有効にして、uWSGI側の設定もこれに合わせる。
3.4 起動設定
設定ファイルが問題ないことを確認して、nginxサービスを起動する。
nginx -t
systemctl start nginx
httpでアクセスして正常に表示できることを確認する。
4.WAF設定
4.1 WAFサーバー設定
WAFサーバー経由での公開設定を行い、正式なSSL証明書を取得する。
4.2 DjangoのSSL設定
Djangoのデプロイチェックで保留していたSSL周りの設定を変更する。SECURE_PROXY_SSL_HEADERを設定する場合は、nginx側で、X-Forwarded-Proto ヘッダーを付与するように設定する。
https://docs.djangoproject.com/ja/3.2/ref/settings/#std:setting-SECURE_PROXY_SSL_HEADER
具体的には以下を追加。
proxy_set_header X-Forwarded-Proto $scheme;
4.3 Naxsi設定
最初はNAXSIを学習モードにして、ルール調整して、最終的にfail2banを有効にする。