Djangoアプリはデプロイしただけだと静的ファイルが読み込まれません。この記事ではその原因と、静的ファイルを読み込むようにする方法について解説します。
目次
- Djangoアプリをデプロイしたら静的ファイルを読まなくなる原因
- Webサーバーで static以下を静的に配信するよう設定
- これだけだとDjangoAdminにCSSが適用されなくなる
- collectstaticを使って静的ファイルを1か所に集める
- apache2.confの静的ファイルの場所を修正
- まとめ
Djangoアプリをデプロイしたら静的ファイルを読まなくなる原因
前回の記事(ConoHa VPSにDjangoアプリをデプロイする方法)ではローカルで作成したDjangoアプリをConohaVPSにデプロイすることができました。
サンプルプロジェクトではHTMLファイルに直接CSSを書き込んでいたので気付きにくかったですが、このままでは static 以下の静的ファイルが読み込まれていません。
試しに /hello/ に外部CSSを適用するページを作成してみると、次のようにCSSが何も適用されていない状態です。
Djangoの開発モード、つまりsettings.pyのDEBUGがTrueの時はデフォルトで静的ファイルを配信してくれます。
DEBUG = True
これは開発時に静的ファイルが読み込まれないと不便なためですが、本番環境では DEBUG = False とするため静的ファイルを自動的に配信してくれなくなります。
DEBUG = True のままだと
- デバッグ情報(ファイルパス、設定内容など)が画面上に出力される(=サイトの攻撃者に優位な情報を渡すことになる)
- SQLクエリを常に保存するのでメモリの消費が激しい
- 本番公開を想定していない機能が多数あるためパフォーマンスが落ちる
といった問題があるので、本番環境では開発モード(DEBUG)はオフ(Flase)にしておく必要があるわけです。
Webサーバーで static以下を静的に配信するよう設定
そもそもDjango自体が静的ファイル配信に最適化されていません。
静的ファイルはDjangoで配信するのではなく、Webサーバーから直接配信するよう設定します。
自作したすべての静的ファイルは、次のようにDjangoプロジェクト直下の static にを置いているものとします。
myproject ├── accounts ├── myapp ├── config ├── static # ここに自作したすべての静的ファイルがある │ ├── css │ ├── images │ └── js └── templates
Apacheのドキュメントルート(パス)に staticファイルのパスが記載されているので変更します。
Alias /static/ /home/django/django-tutorial/static/ <Directory /home/django/django-tutorial/static> Require all granted </Directory>
設定を変更したのでApache2を再起動します。
コンソールなどでサーバーにログインして次のコマンドを実行します。
service apache2 restart
これで static 以下の静的ファイルが読み込まれるようになりました。
これだけだとDjangoAdminにCSSが適用されなくなる
しかしこれだと静的ファイルを参照していた場所を変更しただけなので、DjangoAdminなどに当てていたCSSなどの自動的に生成された静的ファイルが読み込まれません。
つまりDjangoAdminなどのページを開くとCSSが適用されていない状態となります。
Django系のアプリはPythonパッケージの中に静的ファイルを一緒に持っています。
つまり自作した静的ファイルだけでなく、この自動的に生成された静的ファイルも配信する必要があるわけです。
方法としては
- 両方のパスをWebサーバーに設定する
- ファイルの方をコピペしてstaticディレクトリに持ってくる
あたりが考えられますが、もっといい方法があります。
collectstaticを使って静的ファイルを1か所に集める
Djangoには必要な静的ファイルを1つのディレクトリに集約する(コピーして1か所に集める)ための collectstatic というコマンドがmanage.pyに用意されています。
まずはsettings.pyに静的ファイルを集める場所(STATIC_ROOT)を指定します。
import os STATIC_URL = 'static/' STATIC_ROOT = os.path.join(BASE_DIR, 'collected_static') # 静的ファイルを集める場所(STATIC_ROOT)を指定 STATICFILES_DIRS = [BASE_DIR / 'static'] # 追加の静的ファイル探索パス
プロジェクトディレクトリ直下のcollected_staticディレクトリを静的ファイルを集める場所とするよう記述しています。
コンソールなどでサーバーにログインして、collectstatic コマンドで静的ファイルを1つのディレクトリに集めましょう。
cd /home/django/mypeoject python3 manage.py collectstatic >> 129 static files copied to '/home/django/django-tutorial/collected_static'.
このようにコピー完了したよ、的なメッセージが表示されます。
apache2.confの静的ファイルの場所を修正
これでcollected_staticディレクトリにすべての静的ファイルが集まりました。
このディレクトリのファイルをWebサーバーから直接配信するよう、apache2.confの静的ファイルの場所を修正しましょう。
Alias /static/ /home/django/django-tutorial/collected_static/ <Directory /home/django/django-tutorial/collected_static> Require all granted </Directory>
設定を変更したのでApache2を再起動します。
コンソールなどでサーバーにログインして次のコマンドを実行します。
service apache2 restart
これで collected_static 以下の静的ファイルが読み込まれるようになりました。
DjangoAdminのページにもきちんとCSSが適用されています。
まとめ
Djangoアプリのデプロイ時に静的ファイルを読み込むようにするには次の手順。
- collectstatc コマンドで静的ファイルを1か所に集める
- 集約ディレクトリを静的に配信するようWebサーバー側を設定
- collectstatcはデプロイの度に必要になるので、デプロイツールの中で collectstatic を毎回実行させる