はじめに
DockerでNginx+Django環境を動かして開発していた時に、本番環境へのデプロイする際、静的ファイル(staticfile)の扱い周りでちょっと詰まったので解決方法を共有します。
問題点
Djangoでは、静的ファイルの扱いについて、開発時においてはとても扱いやすく作られています。
各アプリケーション下にstaticディレクトリを用意するだけで、開発用サーバを実行した場合はそのまま参照してくれます。
また、本番デプロイ時はpython manage.py collectstatic
を実行することで、静的ファイルを一箇所に集約することができます。
ここで、Dockerの様なコンテナではなく、他の方法で環境を用意した場合を考えます。
コンテナではなく、他の方法で環境を用意した場合、NginxとDjangoアプリケーションは同じ環境で動作していると思います。
この場合では、Nginxの設定で、/static/
のリクエストは直接python manage.py collectstatic
で静的ファイルを集めたディレクトリを参照するように、エイリアスの設定などをすれば問題ありません。
次にコンテナ型の仮想環境で環境を用意した場合を考えます。
コンテナで環境を用意した場合、NginxとDjangoアプリケーションのコンテナを別々に用意し、Dockerのネットワーク機能でこれらのコンテナを接続すると思います。
しかし、この場合ですと、NginxとDjangoアプリケーションのコンテナは別々なため、Nginxコンテナに静的ファイルを配置しなければいけません。
ですが、簡単に自動で環境を構築できる様にするためにDockerを使用しているのに、わざわざ手動でNginxコンテナに静的ファイルを配置するというのは得策ではありません。
そこで、どうにかして、うまいこと本番環境へのデプロイ時には、collectstaticで集約した静的ファイルを参照できないかということを考えて試してみました。
解決策
解決策は単純で、volumeとしてSTATIC_ROOT
をNginxコンテナのルート直下に配置し、ドキュメントルートで指定するという方法です。
今回のアプリケーションでは、アプリケーションコードをvolumeとしてDjangoアプリケーションのコンテナにマウントしていたため、同じ様にstaticディレクトリのみNginxにマウントすればできました。
じゃあ何でハマったのか
ハマった理由としてはパーミッションでした。
始め、staticのマウント先を/root
下に作業ディレクトリを用意して、そこにマウントしていたため、/root
のパーミッションの関係上、Nginxから参照できなくて、403エラーが出る様になってしまいました。
そのため、/root
下以外にマウントすることで、パーミッションがroot以外でも読み取れる様になったので、エラーが出なくなった様です。
この方法の問題点
この方法ですと、docker-composeの様にあくまで同じマシン上でNginxコンテナとDjangoコンテナを稼働させていないといけないため、Kubernetesの様なコンテナオーケストレーションでは使えないといった問題点があります。
実際に運用するにあたってそもそも、一つのマシンで運用するdocker-composeは適さないと思うので、今後改善策を考えたいと思います。