Djangoアプリのデプロイ時に静的ファイルを読み込むようにする方法

Djangoアプリはデプロイしただけだと静的ファイルが読み込まれません。この記事ではその原因と、静的ファイルを読み込むようにする方法について解説します。

目次

Djangoアプリをデプロイしたら静的ファイルを読まなくなる原因

前回の記事(ConoHa VPSにDjangoアプリをデプロイする方法)ではローカルで作成したDjangoアプリをConohaVPSにデプロイすることができました。

サンプルプロジェクトではHTMLファイルに直接CSSを書き込んでいたので気付きにくかったですが、このままでは static 以下の静的ファイルが読み込まれていません。

試しに /hello/ に外部CSSを適用するページを作成してみると、次のようにCSSが何も適用されていない状態です。

CSSが何も適用されていない

Djangoの開発モード、つまりsettings.pyのDEBUGがTrueの時はデフォルトで静的ファイルを配信してくれます。

DEBUG = True

これは開発時に静的ファイルが読み込まれないと不便なためですが、本番環境では DEBUG = False とするため静的ファイルを自動的に配信してくれなくなります。

DEBUG = True のままだと

  • デバッグ情報(ファイルパス、設定内容など)が画面上に出力される(=サイトの攻撃者に優位な情報を渡すことになる)
  • SQLクエリを常に保存するのでメモリの消費が激しい
  • 本番公開を想定していない機能が多数あるためパフォーマンスが落ちる

といった問題があるので、本番環境では開発モード(DEBUG)はオフ(Flase)にしておく必要があるわけです。

Webサーバーで static以下を静的に配信するよう設定

そもそもDjango自体が静的ファイル配信に最適化されていません。

静的ファイルはDjangoで配信するのではなく、Webサーバーから直接配信するよう設定します。

静的ファイルを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 以下の静的ファイルが読み込まれるようになりました。

static 以下の静的ファイルが読み込まれるようになりました

これだけだとDjangoAdminにCSSが適用されなくなる

しかしこれだと静的ファイルを参照していた場所を変更しただけなので、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 を毎回実行させる
このエントリーをはてなブックマークに追加

コメントを残す

頂いたコメントは一読した後表示させて頂いております。
反映まで数日かかる場合もございますがご了承下さい。