はじめに
この記事の続きです。
設定ファイルを編集するところまで。
dockerコンテナに接続
app
はcontainer_name
で指定したもの。
# docker exec -it app bash
設定ディレクトリを作成
以下のコマンドをプロジェクトディレクトリで実行します。
# django-admin startproject config .
config
は任意のプロジェクト名
第二引数に.(カンマ)
を入れることで、config
という設定ディレクトリを作成する。
第二引数を指定しない場合、config
という名前のプロジェクトディレクトリに
config
という同じ名前の設定ディレクトリが作成されてしまうので、ややこしくなってしまいます。
設定ファイルの編集
環境変数を使う
設定は環境変数から読ませるようにする。
Dockerコンテナビルド時に、.env
ファイルに記述した内容がコンテナの環境変数として設定される。
(参考)以下のようにコンテナ内でecho
やprintenv
で確認することができる。
# echo $DJANGO_CONTAINER_NAME
app
環境変数の読み込みは、標準ライブラリのos
を使う。
+ import os
from pathlib import Path
ベースディレクトリ設定
標準設定のまま。
Path(__file__).resolve()
は、settings.pyに対して上の上の階層のディレクトリをベースディレクトリとするという意味。
manage.py
があるディレクトリを設定している。
BASE_DIR = Path(__file__).resolve().parent.parent
シークレットキーの設定
暗号化やハッシュ化で用いられる秘密鍵の指定。
- SECRET_KEY = 'django-insecure-hq2(b=+ap$1lg-69i!+5e@a*az2l119uur&83+h6-1xl%3=_iu'
+ SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY")
+ DJANGO_SECRET_KEY = django-insecure-hq2(b=+ap$1lg-69i!+5e@a*az2l119uur&83+h6-1xl%3=_iu
デバッグモードの設定
.env
で設定したデバッグモード設定がTrueのときにデバッグモードになる。
デバッグモードでは、エラーなどがあるとデバッグメッセージが表示される。
本番デプロイ時はFalseにすること。
- DEBUG = True
+ DEBUG = os.environ.get("DJANGO_DEBUG") == "True"
+ DJANGO_DEBUG = True
許可ホスト設定
許可するIPやドメインを設定する。
ホスト・ヘッダインジェクションに有効。
os.environ.get("DJANGO_ALLOWED_HOSTS").split(" ")
とすることでリスト化して複数設定可能。
開発時は["*"]でよいが、本番適用する場合はドメイン名を入力すること。
- ALLOWED_HOSTS = []
+ ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS").split(" ")
+ DJANGO_ALLOWED_HOSTS = *
自動的にURLにスラッシュを入れてくれる設定
+ APPEND_SLASH = True
アプリケーション
Djangoで利用するアプリケーション。
追加する場合はカンマ区切りで追記する。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
ミドルウェア
Djangoで利用するミドルウェア。
追加する場合はカンマ区切りで追記する。
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ルーティングファイル
最初に呼び出されるルーティングファイル。
ベースディレクトリから見たときの相対パスで記述される。ファイル名は.pyは省略される。
つまり、manage.py
があるディレクトリから見て、./config/urls.py
のパスのファイルを指す。
ROOT_URLCONF = 'config.urls'
HTMLテンプレートディレクトリ
DIRSにHTMLテンプレートを保存するディレクトリのパスを記述する。
ディレクトリは作成しておくこと。
# mkdir templates
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [],
+ 'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGIファイル
WSGIファイルの場所を指定。
PythonはWEB用の言語ではないので、ブラウザで見られるように中間処理が必要。
中間処理を担うのがWSGI(ウィズギー)という仕組み。
今回の構成では、WSGIサーバーとしてGunicornを利用している。
設定は特に変更する必要はない。
WSGI_APPLICATION = 'config.wsgi.application'
データベース設定
デフォルトでは、SQLite3を使う設定になっている。
PostgreSQLを使うために設定を変更する。
利用するデータベースおよびログインユーザーやパスワードなどを記述する。
ATOMIC_REQUESTS
はトランザクション有効化の設定。
DATABASES = {
'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
+ 'ENGINE': 'django.db.backends.postgresql_psycopg2',
- 'NAME': BASE_DIR / 'db.sqlite3',
+ 'NAME': os.environ.get('POSTGRES_DB'),
+ 'HOST': os.environ.get('POSTGRES_ADDR'),
+ 'PORT': os.environ.get('POSTGRES_PORT'),
+ 'USER': os.environ.get('POSTGRES_USER'),
+ 'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
+ 'ATOMIC_REQUESTS': True,
+ 'TIME_ZONE': os.environ.get('TZ'),
}
}
パスワードのバリデーションルール設定
ユーザー名と似たパスワード、パスワード長、よくあるパスワード、数値のみのパスワードをNGにするなどの設定。
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ 'OPTIONS':{"min_length":8},
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
言語設定
英語が標準になってるので日本語に設定。
USE_I18N
は、多言語化機能を有効にするか否かの設定。
- LANGUAGE_CODE = 'en-us'
+ LANGUAGE_CODE = 'ja'
+ USE_I18N = True
地域(タイムゾーン)設定
TIME_ZONE
は、環境変数で設定しているタイムゾーンで設定する。
USE_TZ
は、タイムゾーン変換機能を有効にするか否かの設定(Trueにすると、DBに保存する時間がUTC時間になる)
USE_L10N
をTrueにすると、日付フォーマットがデフォルト値に設定される。
日付フォーマットを変更したい場合は、USE_L10NをFalseに設定した上で、DATE_FORMATで設定する。
- TIME_ZONE = 'UTC'
+ TIME_ZONE = os.environ.get('TZ')
- USE_TZ = True
+ USE_TZ = False
セッション保持設定
SESSION_COOKIE_AGE
でセッションを保持する時間を秒単位で設定する。
この設定だけだと、ログインからの秒数で切れる。
SESSION_SAVE_EVERY_REQUEST
を有効化すると、ログインした状態で最後にページを表示してからの時間で切れるようになる。
SESSION_EXPIRE_AT_BROWSER_CLOSE
を有効にすると、ブラウザを閉じるとセッションが切れる。
+ SESSION_COOKIE_AGE = 3600 * 24
+ SESSION_SAVE_EVERY_REQUEST = True
+ SESSION_EXPIRE_AT_BROWSER_CLOSE = True
静的ファイルを保管するディレクトリの設定
静的ファイルを保存する場所は、2種類(static
とmedia
が)ある。
static
は、アプリケーションに必要なファイルを置く。例えばアプリに必要な画像とか、.jsファイルとか.cssファイルとか。
media
は、ユーザーがアップロードしたPDFや画像などのファイルを置く。
静的ファイルへのアクセスは、Nginxなどのウェブサーバーから直接アクセスさせることで、Django側の負荷を軽減させることができる。
static
ディレクトリとmedia
ディレクトリを作成します。
# mkdir static media
STATIC_URL
は、静的ファイルを保管するディレクトリ。先程作ったやつ。
STATIC_ROOT
は、python manage.py collectstatic
したときに静的ファイルを集めてくるディレクトリ。
python manage.py collectstatic
は、各アプリにある静的ファイルを集めてくるコマンド。
設定していないが、STATICFILES_DIRS
というものがあるが、これは開発環境用のstaticディレクトリの設定らしい。STATIC_ROOT
と重複設定不可。
MEDIA_ROOT
を設定しない場合、ベースディレクトリにアップロードされるので、必ず記載すること
- STATIC_URL = 'static/'
+ STATIC_URL = '/static/'
+ STATIC_ROOT = f'/{BASE_DIR.name}/static'
+ MEDIA_URL = '/media/'
+ MEDIA_ROOT = f'/{BASE_DIR.name}/media'
主キー(PrimaryKey)の設定
モデルにprimary_key=True
を定義しない場合、自動でidという名前の主キーのフィールドが追加される。
- AutoField: IntegerFieldを継承した1~2147483647の範囲
- BigAutoField: BigIntegerFieldを継承した1~9223372036854775807の範囲
- SmallAutoField: SmallIntegerFieldを継承した1~32767の範囲
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
ログ設定
LOG_BASE_DIR
で、ログ保存場所を指定。
version
は、必ず1にします。
disable_existing_loggers
は、設定ファイルで定義されていないloggerの無効化設定(True:全て無効化/False:無効化しない)
formatters
は、ログフォーマット設定。
handlers
は、ハンドラ(ログ出力先)設定。
loggers
は、ロガー(ログ出力オブジェクト)の設定。
root
は、ルートロガー(ロガー設定に当てはまらない場合)の設定。
以下、すべて追記です。
LOG_BASE_DIR = '/logs/django/'
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'production': {
'format': '%(asctime)s [%(levelname)s - %(filename)s:%(lineno)d] %(message)s'
},
},
'handlers': {
# DEBUGログは0.5GBでローテーション(3ファイルまで)
'debug': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
"filename": os.path.join(LOG_BASE_DIR, "debug.log"),
'formatter': 'production',
'maxBytes': 1024 * 1024 * 0.5,
'backupCount': 3,
},
# INFOログは7日で4ファイル(4週間)保管
'info': {
'level': 'INFO',
'class': 'logging.handlers.TimedRotatingFileHandler',
"filename": os.path.join(LOG_BASE_DIR, "info.log"),
'formatter': 'production',
'when': 'D',
'interval': 7,
'backupCount': 4,
},
# ERRORログは7日で4ファイル(4週間)保管
'error': {
'level': 'ERROR',
'class': 'logging.handlers.TimedRotatingFileHandler',
"filename": os.path.join(LOG_BASE_DIR, "error.log"),
'formatter': 'production',
'when': 'D',
'interval': 7,
'backupCount': 4,
},
# Djangoログは0.5GBでローテーション(3ファイルまで)
'django': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
"filename": os.path.join(LOG_BASE_DIR, "django.log"),
'formatter': 'production',
'maxBytes': 1024 * 1024 * 0.5,
'backupCount': 3,
},
# コンソール表示
'console': {
'level': 'DEBUG',
"class": "logging.StreamHandler",
'formatter': 'production',
},
},
'loggers': {
'debug': {
'handlers': ['debug'],
'level': 'DEBUG',
'propagate': True,
},
'info': {
'handlers': ['info'],
'level': 'INFO',
'propagate': True,
},
'error': {
'handlers': ['error'],
'level': 'ERROR',
'propagate': True,
},
'django': {
'handlers': ['django'],
'level': 'DEBUG',
'propagate': True,
},
'console': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': True,
},
},
"root": {
"handlers": ["console"],
"level": "DEBUG",
"propagate": False
},
}
gunicorn設定
Gunicorn起動用の設定ファイルを作成。
# touch config/gunicorn_settings.py
# chmod 666 config/gunicorn_settings.py
wsgi_app = 'config.wsgi:application'
chdir = '/code/'
daemon = False
bind = '0.0.0.0:8080'
workers = 1
accesslog = '/logs/gunicorn/gunicorn_access.log'
errorlog = '/logs/gunicorn/gunicorn_error.log'
コンテナを起動しなおす
コンテナを起動しなおして、.env
を再読み込みさせる。
# exit
# docker-compose down
# docker-compose up -d
再度接続してGunicornが起動していることを確認する。
# docker exec -it app bash
systemctlと同様に、supervisorctl status {プロセス名}
で動作確認可能。
# supervisorctl status gunicorn
gunicorn RUNNING pid 8, uptime 0:00:15
ここまでの状態ではコンテンツがないので、ブラウザで何も表示できない。
これから中身を作っていく必要がある。
続き
こちらの記事に続きます。