前回までのあらすじ
Djangoで作成したアプリをHerokuにデプロイするための基本的な設定を行いました。
環境で設定を使い分ける
settings.py
の例えば環境変数 DEBUGのように、ローカル環境ならTrue、本番環境ではFalseと環境に応じて異なる値をセットする必要があります。
それならと、settings.py
の中でif文を使って条件分岐する方法もあるようですが、よく考えてみてください。
ローカル環境で DEBUG = True
、本番環境で DEBUG = False
と必ず設定されているだろうか?
そのように設定されているかもしれないが、設定されていないかもしれないというのが実際のところだと思います。
そうなると、どうやら一つのファイルで設定方法を分岐させるのは、ベストプラクティスではなさそうです。
それでは、どのようにして分けるべきか?
ローカル環境と本番環境でファイルを分けるという方法がベストプラクティスと言われています。
設定ファイルを分けることで、環境に応じた設定変更が簡単にできたり、設定ミスの低減といったメリットを享受することができます。
本記事では、設定ファイルのsettings.py
をローカル環境と本番環境で切り替えて使用する方法について解説します。
ディレクトリ構成
初めにconfig
ディレクトリ直下にsettings
ディレクトリを作成します。
このディレクトリの中に設定ファイルを格納することになります。
次に__init__.py
ファイルを作成します(ファイルの中身は空でOKです)。
また、既存のsettings.py
をこのディレクトリの中に移動させて、ファイル名をbase.py
に変更します。
このリネームしたbase.py
にローカル環境と本番環境で共通する設定を記述します。
文字通りbaseとなるセッティングファイルです。
そして、ローカル環境と本番環境それぞれに対応する設定を記述するファイルとして、local.py
とproduction.py
を新規作成します。
config
ディレクトリの構成は下図のようになります。
base.pyのBASE_DIRを修正
ディレクトリ構成が変更になったことに伴い、base.py
内で定義しているBASE_DIR
のパスを修正する必要があります。
settings
ディレクトリを追加して階層が一つ増えたので、その部分を次のように修正します。
# 末尾に.parentを追加
BASE_DIR = Path(__file__).resolve().parent.parent.parent
local.pyにローカル環境用の設定を書き込む
では、ローカル環境用の設定をlocal.py
に書いていきます。
初めに書くべきは、共通設定が記述されているbase.py
のインポートです。
from .base import *
あれ?
import *
って書き方は推奨されていないんじゃなかったっけ?
と思われた方もいるかと思いますが、この場合は例外となります。
base.py
で設定されていないものをlocal.py
で追記するので、このような書き方となります。
では、ここからローカル環境独自の設定を書き込んでいきます。
現時点で必要なものは、以下のとおりです。
environ.Env.read_env()
SECRET_KEY
DEBUG
ALLOWED_HOSTS
DATABASES
こちらについては、base.py
の内容をそのままコピペします。
また、base.py
にあるこれらの設定は削除しましょう。
この段階でlocal.py
の内容はこのようになります。
""" ローカル環境で適用される設定内容 """ from .base import * environ.Env.read_env(env_file=str(BASE_DIR) + "/.env") SECRET_KEY = env("SECRET_KEY") DEBUG = True ALLOWED_HOSTS = ['*'] # '*' に変更します DATABASES = { "default": env.db(), }
ひとまずlocal.py
の完成です。
HerokuダッシュボードでSECRET_KEYを設定
さて、ローカル環境の設定がおわったところで、次は本番環境の設定です。
ローカル環境では.env
ファイルを作成して、公開したくない環境変数を記述していました。
公開したくないものですので、.env
ファイルは当然gitignore
の対象となっています。
したがって、本番環境で使う環境変数はHerokuダッシュボードから入力する、または、Heroku CLIで入力する必要があります。
Herokuダッシュボードから作成したアプリを選択して、settingsタブからConfig Varsを編集します。
ここで設定するのは、本番環境用のSECRET_KEY
だけでOKです。
DATABASE_URL
は後ほど設定します。
では、KEYにSECRET_KEY
、VALUEに使用するSECRET_KEYの値
を入力しましょう。
なお、本番環境用のSECRET_KEYの値
はローカル環境と別にすることが望ましいです。
SECRET_KEYの再生成については、こちらの記事を参考に行います。
Heroku CLIを使う場合は、ターミナルから次のように入力します。
$ heroku config:set SECRET_KEY="<本番環境用に取得した値が望ましい>"
DJANGO_SETTINGS_MODULEを設定
これまでは、config
配下のsettings.py
ファイルを自動で読み込んでくれていました。
しかし、今回のように設定ファイルを環境に応じて分けた場合、そのままの設定では上手く動作しません。
読み込む設定ファイルを環境変数DJANGO_SETTINGS_MODULE
を使って指定する必要があります。
まずは、本番環境の設定から行います。
前述のHerokuダッシュボードでSECRET_KEY
の設定と同様に操作します。
KEYにDJANGO_SETTINGS_MODULE
、VALUEにはconfig.settings.production
と入力すればOKです。
要するに、config
配下のsetthings
ディレクトリにあるproduction.py
を指定しているのです。
なお、こちらもHeroku CLIを使ってターミナルから次のように入力してもOKです。
$ heroku config:set DJANGO_SETTINGS_MODULE='config.settings.production'
ならば、ローカル環境も.env
ファイルにそう書けばいいと思ってしまいますが、.env
はDjangoのプロジェクト内に存在するファイルなので、そこに書いては上手く動作しません。
もっと前の段階、そう、docker-compose.yml
内で環境変数を設定するのです。
本番環境の設定と同じように環境変数を設定するには、docker-compose.yml
へ次のようにコードを追記します。
services: web: build: . (略) # この部分を追記 environment: - DJANGO_SETTINGS_MODULE=config.settings.local (略)
production.pyに本番環境用の設定を書き込む
最後に本番環境の設定をproduction.py
に書いていきます。
とはいっても、内容はlocal.py
で記述した値を本番環境向けに修正するくらいです。
では、local.py
の内容をproduction.py
へ丸ごとコピペしましょう。
environ.Env.read_env()
の行は使用しないので、ここでは削除します。
ここで、変更するべきは、DEBUG
とALLOWED_HOSTS
の値です。
修正後のコードはこのようになります。
""" 本番環境(Heroku)で適用される設定内容 """ from .base import * SECRET_KEY = env("SECRET_KEY") DEBUG = False ALLOWED_HOSTS = ['.herokuapp.com'] DATABASES = { "default": env.db(), }
production.py
もこれでひとまず完成です。
おつかれさまでした!
これで、元々あったsettings.py
をローカル環境と本番環境用で分割して、環境に応じた設定を反映させる準備が整いました。
文字にすると工程が長く感じるかもしれませんが、この手順にしたがって設定すると思っているよりもサクッと終わると思います。
できるようになると非常に便利ですので、是非ともファイルの分割に挑戦してみてください。
この記事が環境に応じた設定をどうやって分けたらいいかわからず、困っている方の一助になれば幸いです。
次回は、動作確認と静的ファイル関係の設定について解説する予定です。
では、また次の記事で!✋️