🕌
Djangoアプリをデプロイしたけど、静的ファイルが反映されなかった。
はじめに
- Python, Azureの初学者です。
- Python, Djangoのキャッチアップをしています。
- デプロイはできていたのにstaticディレクトリ内のファイルが反映されませんでした。反映されるまでの流れをまとめます。
- デプロイまでの実装方法は以下のリンクを参照してください。
Azureを使ってDjangoアプリのデプロイをしてみた①(webサーバー編)
Azureを使ってDjangoアプリのデプロイをしてみた②(PostgreSQL編)
使用技術
- Python3.12
- Django
- Azure(App Service)
- PostgreSQL(Azure Database for PostgreSQL Flexible Server)
- Github Actions(開発しているアプリをGithub Actionsで自動デプロイを行っています。)
前提
なぜ静的ファイルが反映されないのか?
- 開発環境では、Djangoが
django.contrib.staticfiles
というアプリケーションを使って、静的ファイルを自動的に提供しています。 - 本番環境では、静的ファイルは通常、Webサーバー(例: NginxやApache)によって提供されるように設定されます。しかし、Djangoのサーバーでは静的ファイルは自動的には提供されないため適切に出力がされません。
解決するには?
-
collectstatic
コマンドを使って静的ファイルをSTATIC_ROOT
にまとめる必要があります。 - これにより、Webサーバーが効率よく静的ファイルを配信できるようになります。
概要
- 静的ファイルの設定。
- whitenoiseの追加。
- collectstaticコマンドを実行。
- requirements.txtの修正。
手順
1. 静的ファイルの設定。
-
settings.py
を書き換えていきます。
- デプロイする時は
DEBUG = False
にしてください。 -
STATIC_ROOT
を作成。
- 開発環境では、静的ファイルは各アプリケーションのstaticフォルダに格納されますが、本番環境にデプロイする際は、これらの静的ファイルを一箇所に集める必要があります。
- Djangoの
collectstatic
コマンドを使って、これらのファイルをSTATIC_ROOT
ディレクトリにまとめます。 - 以下のコードと同じように記載することで、
static
と同じ階層にstaticfiles
が自動で作成されるようになります。 - (
collectstatic
コマンドは後ほど行います。)
BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATE_DIR = os.path.join(BASE_DIR, "templates")
STATIC_DIR = os.path.join(BASE_DIR, 'static')
DEBUG = False
ALLOWED_HOSTS = ['*']
~~~
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
2. whitenoiseの追加。
- 私は今回、PaaSでアプリを動かしています。
-
WhiteNoise
がなくてもデプロイは可能です。 - しかし、外部Webサーバー(NginxやApacheなど)を使って静的ファイルを提供する必要があります。
- IaaS(AWS EC2やGoogle Cloud VMなど)を使用する場合、サーバーから直接静的ファイルにアクセスできるので、
Whitenoise
がなくても良いということです。 - 今回は
WhiteNoise
を使って実装します。
-
whitenoise
のインストール。(デプロイ環境でもインストールをしてください。)
pip install whitenoise
-
MIDDLEWARE
に記載。(下記のコード参照) -
STATICFILES_STORAGE
の記載。
~~~
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
~~~
]
~~~
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
collectstatic
コマンドを実行。
3. - 静的ファイルを
collectstatic
コマンドで1箇所に集めます。 - ローカル環境で行っておけば、サーバー上で行う必要はありません。
python manage.py collectstatic
requirements.txt
の書き換え。
4. pip freeze > requirements.txt
さいごに
- 最後まで読んでくださりありがとうございます。
- 私はrequirements.txt`の書き換えるのを忘れており、実装に時間がかかってしまいました。
- いつかの自分のためにと思い、記事を書きました。
- 誰かの参考になればと思います。
- 誤り等あれば教えてください。
参考文献
Discussion