ikura1's log

備忘録

Django環境の切り替えメモ

[Django]設定ファイルの切り替え

はじめに

Djangoの設定でセキュリティ設定をした場合、開発環境が楽しくない形になるので分けたい。
元々cookiecutter-djangoリポジトリを参考にしていたので、設定ファイルの切り替えを行いたかった。
だけど、Djangoでサイトを作ることを優先したので後回しにしていた。
セキュリティの設定で行う必要が出てきたので、やっていきます。

django-environ

django-environは環境変数の指定が気持ちよくなります。

インストール

pipenv install django-eviron

概要

django-environがないときー

import os

DEBUG = os.environ["DJANGO_DEBUG"]

DATABASES = {
    "default": {
        "ENGINE": os.environ["POSTGRES_ENGINE"],
        "NAME": os.environ["POSTGRES_NAME"],
        "USER": os.environ["POSTGRES_USER"],
        "PASSWORD": os.environ["POSTGRES_PASSWORD"],
        "HOST": os.environ["POSTGRES_HOST"],
        "PORT": os.environ["POSTGRES_PORT"],
    }
}

あるときー!

import environ

DEBUG = env.bool("DJANGO_DEBUG", default=False)

DATABASES = {"default": env.db("DATABASE_URL")}

はい、スマートになりましたね。
最高です。

詰った点

困ったのは、GAEを使っているんですが、CloudSQLの参照設定に詰りました。
ローカルの設定は下記になるんですが、ColudSQLの場合はunix_socketにインスタンス名を指定することを知らずに設定が反映されねえ!!
って悩んでいました。

CloudSQLはhostではなく、unix_socketにインスタンスを設定するんですね。

  • ローカルでの設定
f"mysql://{USER}:{PASSWORD}@{HOST}:{PORT}/{DBNAME}"
"mysql://hoge:hogehoge@127.0.0.1:3306/hoge_db"
  • CloudSQLでの設定
f"mysql://{USER}:{PASSWORD}@/{DB_NAME}?unix_socket=/cloudsql/{INSTANCE_CONNECTION_NAME}"
"mysql://hoge:hogehoge@/hoge_db?unix_socket=/cloudsql/todo:asia-northeast2:todo-db"

環境の分離

フォルダ構成

フォルダ構成をcookiecutterを参考に下記にした。

$ tree ./config/ -I '__pycache__'
./config/
├── __init__.py
├── settings
│   ├── __init__.py
│   ├── base.py
│   ├── local.py
│   └── production.py
├── urls.py
└── wsgi.py

1 directory, 7 files

cookiecutterはローカルと本番以外に、test環境用の設定が存在する。
テストコードがまだ書けていないので、今回は保留して後日追加します。

開発と本番での設定分離

開発環境で設定すると閲覧できなくなるセキュリティ回りやDBの参照回りを本番のみの設定として、他はbaseで共有するという形です。
設定でわからない部分がありますが、cookiecutter-djangoでは設定項目の上にドキュメントのurlが書いてあるので非常に助かる。
作成は参考にしつつ、コピペしつつ、書きつつといった感じです。

↓は添付用にざっくり削ってます。
開発

# local.py
from .base import *
from .base import env

# GENERAL
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#debug
DEBUG = True
# https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
# localと本番で同じDBを使っているため今はenvを参照している
# TODO: 設定回りの調整が終わり次第, DBを分離させる
SECRET_KEY = env(
    "DJANGO_SECRET_KEY",
    default="ObpY86bMfPs0X5HfluLGFslLDFnHdLQ2sjR8QX17xivRR0XRPFK7fMU0uqWE10nK",
)

ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1"]

本番

# production.py
from .base import *
from .base import env

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env("DJANGO_SECRET_KEY")

ALLOWED_HOSTS = ["timetask.appspot.com"]

# ADMIN
# ------------------------------------------------------------------------------
ADMIN_URL = env("DJANGO_ADMIN_URL")

# SECURITY
# ------------------------------------------------------------------------------
# HSTS
# SECURE_HSTS_SECONDS = 518400
# https://docs.djangoproject.com/en/dev/topics/security/#ssl-https
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-seconds
# TODO: set this to 60 seconds first and then to 518400 once you prove the former works
SECURE_HSTS_SECONDS = 60
SECURE_HSTS_INCLUDE = True
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-include-subdomains
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-preload
SECURE_HSTS_PRELOAD = True

参照の切り替え

参照元をsettings.pyのところをsettings.localとsettings.productionに切り替えました。

  • Before
# wsgi.py
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
# manage.py
def main():
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
  • After
# wsgi.py
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production")
# manage.py
def main():
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")

次にやること

  • セキュリティ項目でわからんことのドキュメント読む
  • テスト書く
  • ファイルアップロード回りの実装
    • アカウントアイコンにする

参考サイト

https://github.com/audreyr/cookiecutter

https://github.com/pydanny/cookiecutter-django

https://qiita.com/moonwalkerpoday/items/9da47dda80d3ddac9a62