今回のテーマは「DjangoのStaticファイルの扱い」です。ここまでローカルの開発サーバでDjangoアプリを開発してきた方はstaticファイルの置き場所は既に設定済みという認識だと思います。しかし、本番環境にデプロイする際にはstaticファイルの参照先を変える必要があります。今回はデプロイ時を想定してStaticファイルの取り扱いについて見ていきたいと思います。
DjangoにおけるStaticファイルの扱い
Djangoに限らずWEBアプリケーション全般の話ですが、実行プログラムとStatic(静的)ファイルの配置場所を分ける傾向にあります。これはStaticファイルへのリクエストを切り離すことでアプリケーション側の負荷を減らしStaticファイルの読み込み効率UPを考慮したものです。尤も近年はキャッシュを用いて高速にStaticファイルを配信する技術もあるで、古いノウハウとなりつつありますがロジックを担当するアプリケーションと読み込まれるだけのStaticファイルを分離するという考え方はまだ生きていると思います。
しかし開発時にアプリケーションとStaticファイルを分離してしまうと開発が困難(というか面倒)となり作業効率が悪くなります。そこでDjangoは開発時に取り扱ったStaticなファイルを本番環境用のディレクトリにそっくりコピーするという戦略を取っています。開発時にはsettings.pyのSTATICFILES_DIRSに登録されたディレクトリを参照しています。
公式ドキュメントでは
https://docs.djangoproject.com/ja/2.1/howto/static-files/
が該当ページとなります。
設定パラメータとファイルコピーのためのコマンド
Staticファイルに関するパラメータ
ここでsettings.pyで設定するStaticファイルに関する設定パラメータを見ていきましょう。
- STATICFILES_DIRS: 開発時のStaticファイルを置くディレクトリ
- STATIC_ROOT: 本番環境用のStaticファイルを置くディレクトリ
- STATIC_URL: テンプレート上でstaticモジュールを使用した時のURL
STATICFILES_DIRSとSTATIC_URLに関しては1-5. staticファイルを扱うで設定している通り、開発中のStaticファイルを置く場所です。DjangoはStaticファイルにアクセスするように指示を受けると開発時であればSTATICFILES_DIRSにあるファイルを探しに行きます。この時、それらのディレクトリにアクセスするURLはSTATIC_URLで設定したURLとなります。
問題はSTATIC_ROOTです。これが本番時にファイルを設置する場所となります。このパラメータを設定しておくことで後述のコマンドで開発で使用したファイルをコピーする先を指定することになります。
ファイルコピー用のコマンド
では本番環境用にSTATIC_ROOTにファイルをコピーするにはどうすれば良いのでしょうか?DjangoにはSTATIC_ROOTへファイルをコピーするコマンドが用意されています。
(venv)$ ./manage.py collectstatic
このコマンドでSTATIC_ROOTで設定したディレクトリにファイルがコピーされます。
NginxやuWSGIでのStaticファイル置き場の設定
ここまでStaticファイルの置き場所について見てきました。DjangoにとってSTATIC_ROOTで指定されたディレクトリは単にコピー先であって、ルーティングの対象外となります。においてCSSが適用されたなかった理由がお分かり頂けたと思います。
では、本番環境でStaticファイルにアクセスするにはどうしたら良いのでしょうか?ここから先の話はDjangoとはあまり関係のない話になります。要はユーザーからSTATIC_URLにアクセスがあった時にSTATIC_ROOTのディレクトリにアクセスするように設定をすれば良いということです。今回はNginx + uWSGIで構成を考えていますのでNginxで設定する場合とuWSGIで設定する場合の2通りを見ていきましょう。
Nginxで設定する場合
ネットで多く紹介されている方法がNginxでディレクトリを設定する方法です。これは単純にSTATIC_URLにアクセスされた場合のルートディレクトリを指定するというものです。
server {
... 省略
location /static/ {
root STATIC_ROOTディレクトリへのpath;
}
... 省略
}
uWSGIで設定する場合
NginxにアクセスされたリクエストをすべてuWSGIに流して、StaticファイルへのアクセスはuWSGIで処理するよういうことも出来ます。今回はで作成したuwsgi.iniに”static-map”の項目を追加しましょう。このuwsgi.iniはローカルで動かすための設定ですが、本番環境でも基本は変わりません。
[uwsgi]
chdir = {Djangoアプリのプロジェクトルート}
module = mysite.wsgi:application
static-map = /static={STATIC_ROOTのディレクトリパス}
http = 0.0.0.0:8000
最後に
uWSGIでDjangoアプリを動かしたり、サーバーにデプロイした際にStaticファイルが反映されず焦る方もいるかも知れません。この記事がなにかのお役に立てば幸いです。次回はサーバーにDjangoアプリをデプロイする作業を見ていこうと思います。
Sponsored Link