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を有効にする。