【前編】【Django+Nginx+Gunicorn】アプリケーションをEC2へデプロイしよう
Django でアプリケーションを作成したのでサーバーへデプロイします
ただ、サーバーへのデプロイ方法は本に書いてないこともあり、Linux 等の知識も必要なため、なかなかハードルが高い
そこで、Django をサーバーへデプロイする方法をご紹介します
システムのイメージ
(各役割)
Nginx:ユーザーからのアクセスに対して、静的ファイルを呼び出す or Gunicorn へ処理を振る
Gunicorn:Django と Nginx をつなぐもの
Django:Python のフレームワーク
PostgreSQL:Django が使用するデータベース
なので、
- ユーザーがブラウザからアクセスする
- Nginx で処理する
- Python を呼び出す場合は Gunicorn 経由で Django に処理を振る
- ユーザーにレスポンスを返す
というのが今回のシステムのイメージです
デプロイの流れ
(前提)
Django でアプリを作成済み
- デプロイするために、Django のソースを変更する
- EC2(サーバー)を起動する
- EC2 に nginx, Python, postgreSQL をインストールする
- ソースをアップロードする
- PostgreSQL の設定をする
- Gunicorn をインストールする
- Django をデーモン化する
- Nginx の設定をする
- ブラウザからアクセスして確認する
Django の準備をする
以下のことを行います
- 環境ごとに読み込む設定ファイルを変える
- ライブラリ情報を書き出す
- Django プロジェクトを zip にする
環境ごとに読み込む設定ファイルを変える
DEBUG や DATABSE など、 ローカル環境とサーバーにデプロイ後で値を変えたいものがあると思います。
デフォルトのままだと、settings.pyという1つのファイルになっており、 環境ごとに値を分けることが難しいです。
そこで、以下の手順でsettings.py の構成を変更します
(手順)
- settings ディレクトリを作成し、その中に環境ごとのファイルを作成する
- base.pyには共通の設定値を記載する
- dev.py, production.pyには環境ごとの設定値を記載する
- manage.py , wsgi.pyを修正する
settings ディレクトリを作成し、その中に環境ごとのファイルを作成する
- settings.py がある階層に settings ディレクトリを作成する
- settings.py → base.py にリネームし、settings ディレクトリに移動する
- settings ディレクトリに __init__.py , dev.py , production.pyを作成する
(作業前)
(作業後)
base.py には共通の設定値を記載する
BASE_DIR , INSTALLED_APPS , MIDDLEWARE など 環境に左右されない値を base.py に残します
また、manage.py の場所を示す BASE_DIR の値を変更します。
理由は、デフォルトの設定ではbase.py(旧 settings.py)の 1 つ上の階層を指定しているからです。
先ほど、ディレクトリの階層を 1 つ深くしましたので、 現在は base.py から見ると 2 つ上の階層に manage.py があるため、そのように値を修正します。
# 修正前
BASE_DIR = Path(__file__).resolve().parent.parent
# 修正後
BASE_DIR = Path(__file__).resolve().parent.parent.parent
dev.py, production.py には環境ごとの設定値を記載する
1 行目に下記を記載して、base.py の値を読み取るようにします。
from <Djangoのプロジェクト名>.settings.base import *
あとは、環境固有の値を記載していきます
具体的には
- SECRET_KEY
- DEBUG
- DATABASES
- ALLOWED_HOSTS
- STATIC_ROOT, STATIC_ROOTなど...
ローカル環境で、django-silkや django-debug-toolbarを使用している場合は dev.py に以下を記載しましょう
INSTALLED_APPS += [
"debug_toolbar",
"silk",
]
MIDDLEWARE += [
"debug_toolbar.middleware.DebugToolbarMiddleware",
"silk.middleware.SilkyMiddleware",
]
production.pyには、以下の値を指定しましょう
DEBUG = False
# EIPを設定していない場合は、「"*"」を設定しておくとよいが、セキュリティ的には少し不安
ALLOWED_HOSTS = ["<パブリックIP or DNS>"]
# PostgreSQLを使用するようにする
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": "djangodatabase", # データベース名
"USER": "djangouser", # ユーザー名
"PASSWORD": "djangopassword", # パスワード
"HOST": "localhost",
"PORT": "5432",
}
}
# collectstaticしたときに集めたstaticファイルを置く場所 絶対パス
# OSのルートからの絶対パス
STATIC_ROOT = '/usr/share/nginx/html/static'
MEDIA_ROOT = '/usr/share/nginx/html/media'
manage.py , wsgi.py を修正する
デフォルトで local 環境の設定を読み込むように 2 つのファイルを修正します
# 変更前
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<Djangoのプロジェクト名>.settings')
# 変更後
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '<Djangoのプロジェクト名>.settings.dev')
ライブラリ情報を書き出す
Django プロジェクトのルートディレクトリ(manage.py と同じ階層)で 下記のコマンドを使用してライブラリの情報をテキストに出力します
pip freeze > requirements.txt
実行すると、Django プロジェクトのルートディレクトリに requirements.txtが作成されます。
中身を見ると、環境にインストールしているライブラリとそのバージョンが記載されています
(中身の例)
appdirs==1.4.4
asgiref==3.5.2
astroid==2.11.7
asttokens==2.0.8
autopep8==1.7.0
backcall==0.2.0
black==22.6.0
charset-normalizer==2.1.1
click==8.1.3
colorama==0.4.5
cssbeautifier==1.14.5
decorator==5.1.1
dill==0.3.5.1
Django==4.0.6
django-bootstrap5==22.1
django-debug-toolbar==3.6.0
django-extensions==3.2.0
django-pygments-renderer==0.0.1
django-silk==5.0.1
djlint==1.12.0
EditorConfig==0.12.3
executing==0.10.0
...
このファイルをもとにサーバーの Python にも同じライブラリをインストールします
Django プロジェクトを zip ファイルにする
エクスプローラーで zip 化していきます
- zip 化したいフォルダを右クリックする
- 「送る」をクリックする
- 「圧縮(zip 形式)フォルダー」をクリックする
- zip ファイルが作成されます
Linux や Mac の場合、下記コマンドで zip ファイルにできます
zip -r <zip ファイル名> <zip ファイルにしたいフォルダ>
これで、Django の下準備は完了です。
EC2 を起動しよう
下記の記事を参考に EC2 を起動します
また、コストがかかってしまうのですが、EIP を付与しておくと便利です
使用ツールのインストール
Nginx
下記の記事を参考に Nginx をインストールします
Python
下記の記事を参考に Python をインストールします
PostgreSQL
下記の記事を参考に PostgreSQL をインストールします
残りの作業は後編をご参考ください
参考文献
Discussion