[Django]サーバーの構築

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

流れとしては、以下の順に順次確認して最終系にする。

  1. Django
  2. uWSGI –> Django
  3. nginx –> uWSGI –> Django
  4. 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を有効にする。