2021.06.13  

【Django】debug=False設定時staticとmediaのファイルが読み込めない事象の解決


先日著者がDjangoのデバックモードを解除(DEBUGをFalseに設定)した際、staticとmediaに配置した画像やファイルが読み込めなくなってしまいました。

本記事ではその解決方法について紹介します。

DjangoのDEBUG設定とは

Djangoでエラーが発生したときに多くの情報を提供してくれます。

DEBUGを有効にするにはsettings.pyでDEBUG=Trueと記載します。

settings.py
DEBUG=True

しかし、本番環境でもDEBUGが有効になっていると、エラー時にユーザーにもエラーの詳細情報が表示されてしまいます。

これはセキュリティ上よろしくないということで、本番リリース時はDEBUGをTrueに設定してはいけないとマニュアルにも記載されています。Django: DEBUG

staticとmediaが読み込めなかった原因

Webサーバー(Nginx)にstaticとmediaのファイルを配置されておらず、適切な設定も行われていなかったため。

DEBUG=FalseとTrueの扱いについて

前提としてsettings.pyに以下の設定がされているものとします。

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を以下のようにします。

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に記載してあります。

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を次のように設定します。

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を次のように設定します。

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でまず静的ファイルのみ表示してみる

コメント
現在コメントはありません。
コメントする
コメント入力

名前 (※ 必須)

メールアドレス (※ 必須 画面には表示されません)

送信