この記事について
Djangoで本番運用やチーム開発を行うに当たって、プロジェクトの初期構成にどのように手を入れたらよいかを、The Twelve Factorsなどを参考にまとめたメモです。
参考:
- The Twelve Factors
- Two Scoops of Django 1.11
- cookiecutter-django
- Django の settings を切り替えるようにした話
- Django の設定ファイル settings.py の環境毎の切り替え方法について検討する
設定ファイルの分割の目的
問題点
Djangoの設定ファイルを本番用と開発用に分ける方法としてはlocal_settings.py
を使う方法がよく紹介されます。
参考:https://djangogirlsjapan.gitbooks.io/workshop_tutorialjp/deploy/
しかし、Two Scoops of Django 1.11 ではこの方法に以下の問題点があると指摘しています。
- 設定が増えてくると本番環境と開発環境の設定の違いがわかりづらい。
- 開発環境の設定(
local_settings.py
)がリポジトリに無いので、開発ノウハウが開発者個人に留まり共有されない。
Djangoのベストプラクティスを集めたテンプレート出力ツール「cookiecutter-django」では、本番用と開発用の両方の設定ファイルを作成し、起動スクリプトでどちらを呼ぶか指定する方法を採っています。今回はこれを手法を模倣します。
設定方法
初期構成から変更を加えるファイルは以下の通りです。
設定ファイルを読み込む場所はプロジェクト内で2か所なので、そこを本番用と開発用に分けてしまうという方針です。
base_dir
├ manage.py # [更新] 開発環境の起動スクリプト
└ config
├ wsgi.py # [更新] 本番環境の起動スクリプト
└ settings # [新規] 設定ファイルディレクトリ
├ __init__.py # [新規]
├ base.py # [新規] 共通設定 ※元のsettings.pyを使う
├ local.py # [新規] 開発環境設定
└ production.py # [新規] 本番環境設定
作業手順
手順1
まず元々の設定ファイルsettings.py
のあるディレクトリにsettingsディレクトリを作ります。
手順2
ディレクトリ「settings
」にsettings.py
を移動して、ファイル名をbase.py
に変更します。
手順3
base.py
の最初の方のBASE_DIR
の指定を編集します。設定ファイルの場所が1階層深くなるので入れ子を一つ増やします。
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# ↓↓
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
※ django-environを使って以下のようにもできます。
import environ
ROOT_DIR = environ.Path(__file__) - 3
手順4
個別設定になる項目を共通設定より削除します。
個別設定の例:
- DEBUG:デバッグフラグ(開発:Ture / 本番:False)
- DATABASE:データベース接続
- MEDIA_ROOT等:ストレージ設定
- STATIC_ROOT:静的ファイル配置
- LOGGING:ログ出力
手順5
新規に開発用設定ファイル(local.py)と本番用設定(production.py)ファイルを作ります。ファイルの先頭には共通設定ファイルへの参照を記述します。
from .base import *
その後、それぞれの個別設定を追加します。
※ 共有設定の項目(配列)に追加する場合は以下の様にする
INSTALLED_APPS += (
'debug_toolbar', # and other apps for local development
)
手順6
起動スクリプトとなる manage.py(開発用)とwsgi.py(本番用)の設定ファイルの指定箇所をそれぞれ変更します。
変更前
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
変更後
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production")
注意点
本番環境でmanage.pyコマンドを実行する場合は、あらかじめ環境変数DJANGO_SETTINGS_MODULE
にconfig.settings.production
を設定するか、manage.pyの起動オプションに--settings config.settings.production
を指定する必要がある。
例:Heroku
heroku config:set DJANGO_SETTINGS_MODULE=mysite.settings.production