先日著者がDjangoのデバックモードを解除(DEBUGをFalseに設定)した際、staticとmediaに配置した画像やファイルが読み込めなくなってしまいました。
本記事ではその解決方法について紹介します。
DjangoのDEBUG設定とは
Djangoでエラーが発生したときに多くの情報を提供してくれます。
DEBUGを有効にするにはsettings.pyでDEBUG=Trueと記載します。
DEBUG=True
しかし、本番環境でもDEBUGが有効になっていると、エラー時にユーザーにもエラーの詳細情報が表示されてしまいます。
これはセキュリティ上よろしくないということで、本番リリース時はDEBUGをTrueに設定してはいけないとマニュアルにも記載されています。Django: DEBUG
staticとmediaが読み込めなかった原因
Webサーバー(Nginx)にstaticとmediaのファイルを配置されておらず、適切な設定も行われていなかったため。
DEBUG=FalseとTrueの扱いについて
前提としてsettings.pyに以下の設定がされているものとします。
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
STATIC_ROOT = os.path.join(BASE_DIR, 'app/static')
MEDIA_ROOT = os.path.join(BASE_DIR, 'app/media/')
DEBUG=True と設定すると、本来Webサーバーを経由してstaticやmediaのファイルを読み込むところをdjangoアプリ内のstaticとmediaを見に行くように設定することができます。
その設定を行うには、project側のurls.pyを以下のようにします。
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# -- 省略 --
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
著者の環境ではこの設定が行われていたので、DEBUG=True時は問題なくstaticとmediaのファイルが読み込めていました。
しかし、DEBUG=False(本番想定の設定)を行うとこれらの設定が無効になります。
マニュアルにもそのように記載されています。
マニュアル
Django: 開発中の静的ファイルの提供
Django: 開発中にユーザーがアップロードしたファイルを提供する
そういう訳で、staticとmediaのファイルをWebサーバー経由で読み込めるよう設定してあげる必要があります。
Webサーバー(Nginx)の設定
staticとmediaのファイルは、DEBUG=True時、Webサーバーのドキュメントルートを参照します。
ドキュメントルートとは、簡単に言えばURLのドメインの最後 「/ 」以降のディレクトリのことです。(例: https://example.com/)
Django側の設定は先ほど確認したsettings.pyに記載してあります。
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
STATIC_ROOT = os.path.join(BASE_DIR, 'app/static')
MEDIA_ROOT = os.path.join(BASE_DIR, 'app/media/')
nginxの場合はnginx.confを次のように設定します。
server {
# -- 省略 --
location /static {
alias /usr/share/nginx/html/static;
}
location /media {
alias /usr/share/nginx/html/media;
}
設定が終わったら上記のaliasで設定した通りのディレクトリにstaticとmediaのファイルを配置します。
著者の環境はDocker-Cmposeであるため別の方法で実施しましたが、一般的には以下のコマンドを実行すことで、Djangoが自動でファイルを配置してくれるようです。
python manage.py collectstatic
Docker-Compose使用時の設定
Docker-Compose使用時はnginx.confを次のように設定します。
server {
# -- 省略 --
location /static {
alias /web_app_src/static;
}
location /media {
alias /web_app_src/media;
}
次にdocker-compose.ymlを修正します。
services:
nginx:
image: nginx:1.xx
ports:
# -- 省略 --
volumes:
# -- 省略 --
# 次の2行を追加
- ./src/app/static:/web_app_src/static
- ./src/app/media:/web_app_src/media
depends_on:
- python
こうすることで、Django専用ディレクトリ(ローカル)の/src/app/staticと/src/app/mediaをNginxコンテナの/web_app_src/staticと/web_app_src/mediaディレクトリに配置することができます。
この状態でDEBUG=Falseを設定すると無事ファイルが読み込めるようになっています。
Djangoの参考書
参考
DEBUG=TrueとFalseの違いを解説【公開前にFalseにする理由】
Django staticファイル まとめ)
Nginxでまず静的ファイルのみ表示してみる