概要
Djangoのアプリを作成した後、本番環境(ローカル)へデプロイをした際に、躓いたのでメモがわりに記載します。
つまづいたポイントとして、DjnagoアプリとNginxの連携が上手くいかず、本来表示される予定のページにてHelloページ(デフォルトページ)が表示されたことです。
もし、同じ悩みを持った人や同じことをしようとしている人がいれば参考にしていただければ幸いです。
※誰でも理解できるように記載を行っているつもりですが、ある程度のDjangoの知識が必要だと思います。
前提
前提として、Djangoアプリの開発が完了 + MySQLの構築 + Nginxのインストールが完了している程で進みます。これらができていない方は、こちらの方々の記事を参考にすると構築ができると思います。
MySQLの構築:
nginx(最新)のインストール:
- フレームワーク: Django == 4.2.5
- DB: MySQL == 8.0.34
- APサーバ: Gunicorn == 21.2.0
- Webサーバ: Nginx == 1.24.0
- Python: python3.10.12
使用した環境
重要なのはサーバのOSだけだと思いますが記載します。
- server
- OS: Ubuntu22.04 LTS
- client
- OS: MacOS Ventura 13.4.1(c)
構想
以下の構想で実装を行いました。
ディレクトリ構想
重要なのはyourproject/yourproject/settings.pyのみです。app1などはそれぞれのアプリを指します。
.
├── bin # 仮想環境
└── yourproject # それぞれのプロジェクト
├── app1
├── app2
├── app3
├── yourproject
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py # 今回はここだけ変更します
│ ├── urls.py
│ └── wsgi.py
└── templates
├── app1
├── app2
└── app3
手順
-
Djangoアプリケーションの作成(ここは省略させていただきます)
-
apt、pipの更新
sudo apt update python3 -m pip install --upgrade pip
-
virtualenvのインストール
python3 -m pip install virtualenv
-
仮想環境の構築とアクティブ化
$ sudo apt install python3.10-venv $ python3 -m venv . $ source bin/activate
ここまでが完了したらターミナルのユーザ名の前に
(作業しているディレクトリ名)hoge@hoge:~/...$みたいに記載されているはずです。 -
仮想環境に必須なものをインストール
$ python3 -m pip install django gunicorn psycopg2-binary $ sudo apt install curl
上記のものは必須です。
その他必要なものもこの時にpipしておきましょう。
後に、runserverした時に不足しているものは表示されるので随時インストールでもokです。 -
Djangoアプリのsettings.pyを編集
yourproject/yourproject/settings.py$ cd yourproject/yourproject $ vi settings.py # 以下の部分を編集してください ALLOWED_HOSTS = ['*'] # importのみファイルの先頭に記載 import os STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
編集できたらエディタは何を使っても構いません。vscodeでもokです。
今回はセキュリティは考慮していません。従って、ALLOWED_HOSTS = ['*']としていますが、本来であれば、使うIPだけを許可してください
-
データベースのマイグレーションとアドミンユーザの作成
yourproject$ python3 manage.py makemigrations $ python3 manage.py migrate $ python3 manage.py createsuperuser # コンソールに色々記載しますが、推測されないユーザを作りましょう。
すでにマイグレーションとアドミンユーザを作っている場合は飛ばして構いません
-
staticファイルの収集
yourproject$ python3 manage.py collectstatic
-
ファイアウォールの設定
yourproject$ sudo ufw allow 8000
-
Djangoアプリが起動するか確認
yourproject$ python3 manage.py runserver
-
Gunicornを使って起動するか確認
yourproject$ gunicorn --bind 0.0.0.0:8000 yourproject.wsgi
settings.pyがあるディレクトリに各自移動して実行してください。
一旦、ブラウザで
http://自分のip:8000
を見てアプリの画面が出ていたらokです。 -
systemdソケットの作成
$ sudo vi /etc/systemd/system/gunicorn.socket # 以下の内容を記載してください [Unit] Description=gunicorn socket [Socket] ListenStream=/run/gunicorn.sock [Install] WantedBy=sockets.target
-
サービスファイルの作成
$ sudo vi /etc/systemd/system/gunicorn.service # 以下の内容を適宜変更して記載してください("()"は必ず削除してください) [Unit] Description=gunicorn daemon Requires=gunicorn.socket After=network.target [Service] User=sammy(Ubuntuのユーザー名) Group=sammy (Ubuntuのユーザ名でok) WorkingDirectory=/home/sammy/yourprojectdir (settings.pyの一個上の階層のパス) ExecStart=/home/sammy/yourprojectdir/bin/gunicorn \ (bin/gunicornのあるパス) --access-logfile - \ --workers 3 \ --bind unix:/run/gunicorn.sock \ yourproject.wsgi:application(yourprojectは作成したアプリ名) [Install] WantedBy=multi-user.target
その他の設定(タイムアウト)は,公式ドキュメントを参考にしてください.
https://docs.gunicorn.org/en/stable/settings.html -
Gunicornソケットの実行とソケットのアクティブ化
$ sudo systemctl start gunicorn.socket $ sudo systemctl enable gunicorn.socket $ sudo systemctl status gunicorn.socket
statusでActiveがactiveになっておればokです。あとはgunicorn.socketの前に緑色の⚪︎があれば起動完了です。
-
Gunicorn.sockのファイルがあるか確認
$ file /run/gunicorn.sock # 下記の画面が表示されたらok /run/gunicorn.sock: socket
ここでつまづいたら、おそらくソケットの作成ができていません。従って下記のコマンドでデバッグしましょう。
$ sudo journalctl -u gunicorn.socket
-
疎通確認
$ sudo systemctl status gunicorn $ curl --unix-socket /run/gunicorn.sock localhost # ここでhtmlのレスポンス(200)が返却されたらokです。 $ sudo systemctl daemon-reload $ sudo systemctl restart gunicorn $ sudo systemctl start nginx
-
nginxのGunicornのプロキシを設定
$ sudo vi /etc/nginx/conf.d/yourproject.conf # 下記の内容を適宜変更して記載してください server { listen 80; server_name server_IP; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /home/sammy/yourprojectdir; } location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://unix:/run/gunicorn.sock; } } $ sudo rm /etc/nginx/conf.d/default.conf
この時にインデントに注意してください。筆者はここのインデントを間違えて躓いていました。
-
nginxに間違いがないか確認
$ sudo nginx -t # 下記の画面が表示されたらok nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful $ sudo systemctl restart nginx
-
ファイアウォールの設定
$ sudo ufw delete allow 8000 $ sudo ufw app list $ sudo ufw allow 80,443/tcp $ sudo vi /etc/ufw/applications.d/nginx.ini # 下記の内容を記載 [Nginx HTTP] title=Web Server description=Enable NGINX HTTP traffic ports=80/tcp [Nginx HTTPS] \ title=Web Server (HTTPS) \ description=Enable NGINX HTTPS traffic ports=443/tcp [Nginx Full] title=Web Server (HTTP,HTTPS) description=Enable NGINX HTTP and HTTPS traffic ports=80,443/tcp $ sudo ufw app update nginx $ sudo ufw app info 'Nginx HTTP' $ sudo ufw allow 'Nginx HTTP' $ sudo ufw allow 'Nginx Full' $ sudo ufw status $ sudo ufw enable
-
疎通確認(最後)
http://自分のip
にアクセスを行うと、Djangoのアプリが見れるはずです。(もしかしたらcssが崩れている可能性があります)
終わりに
同じ悩みの人が実行できていれば幸いです。
余談ですが、やはりDockerを用いた方が簡単なのでしょうか?有識者の方がいたら教えていただきたいです。
また間違い等がございましたら、ご連絡ください。
最後まで見ていただきありがとうございました。
参考文献