DjangoをHerokuにデプロイするも500エラー : Staticファイルに関わる原因を調べる

Django

Djangoで作った自作WEBシステムをHerokuにデプロイした際に、ビルド自体は成功するものの500エラーが返ってきてしまう現象に遭遇しました。原因はStaticファイルに関わる設定にあったようで、Django側の設定を変更して500エラーを解決できました。しかし、このあたりの設定について理解できていないことが多いのでここに調査して整理しておきます。

なお、原因とその解決できた理由について完全に理解するに至っていませんが、解決に至るまで調査したことと解決のために行ったことについて記載します。現在DjangoとHerokuの設定ついて引き続き調査中です。

500エラー以前に、デプロイが失敗するとき

collectstaticコマンドが失敗する

DjangoをHerokuにデプロイする際に、自動的にDjangoのcollectstaticというコマンドが実行されます。Herokuのドキュメントにも記載があります。

python manage.py collectstatic --noinput
Django と静的アセット | Heroku Dev Center
静的アセットを使用するように Heroku 上の Django アプリケーションを正しく設定する方法について学習します。

この際にDjangoのStaticファイルの設定が正しくない場合ビルドが失敗します。

(Staticファイルを使っていないなら)collectstaticの自動実行を止められる

もし自分のDjangoプロジェクトでStaticファイル(静的ファイル:CSSや画像ファイルなど)を使っていない場合には以下のコマンドでcollectstaticをビルド時にさせないようにできます。

heroku config:set DISABLE_COLLECTSTATIC=1

ネットでHerokuへのデプロイに失敗する事例を調べて見つかる「DISABLE_COLLECTSTATICを無効にして解決しました!」という情報は、Staticファイルを使っていないプロジェクトの話だと思います。

Staticファイルを使っているならcollectstaticの無効化では解決しない

もし自分のDjangoプロジェクトがStaticファイルを使っているのにDISABLE_COLLECTSTATICを設定すると、collectstaticを実行せずエラーを出さないので一見ビルドが成功します。

しかし、いざアプリケーションにアクセスしてみると、おそらく500エラーを返してきます。

つまりDISABLE_COLLECTSTATICを設定せずに、Staticファイルの設定を正しく行う必要があります。

500エラーが出る時

500エラーが出る原因はStaticファイルの設定によるものだけとは限りませんが、ここではStaticファイルの設定に関わるものが原因と考えられる500エラーの解決策を調査した内容について書きます。

Heroku公式に記載のStaticファイルの設定

HerokuのドキュメントにStaticファイルの設定について記載されています。

Django と静的アセット | Heroku Dev Center
静的アセットを使用するように Heroku 上の Django アプリケーションを正しく設定する方法について学習します。
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'

# Extra places for collectstatic to find static files.
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

公式に記載されている内容ですので、自分のプロジェクトでもこちらに従い設定しました。(しかしcollectstatic時にエラーとなる)

Staticファイルの設定項目を確認

Djangoのsettings.pyに記載するStaticファイルの設定項目は正直なところイマイチわかりづらいと感じますが、ネットで検索すると参考になる記事が見つかりますのでご紹介します。

Djangoにおける静的ファイル(static file)の取り扱い - Qiita
DjangoのチュートリアルやUdemyの授業を進める中で、理解できなかったsettings.pyの下の方に追記する、STATICFILES_DIRSやSTATIC_ROOT、STATIC_URLに…
【django】静的ファイル(CSS、JavaScript、Image)の保存場所や設定について | OFFICE54
本記事ではPythonのWebフレームワークであるdjangoにおける、静的ファイル(CSS、JavaScript、Image)の保存場所や設定について解説していきます。CSSやJavaScriptをdjangoに適用させるには、適切な場所にファイル群を置き、適切な設定をする必要があります。

STATIC_ROOTはHerokuのドキュメントでは「staticfiles」としており、自分のDjangoプロジェクトにも予めこのディレクトリを作っておきます。そして、collectstaticコマンドが実行された際には、このstaticfilesディレクトリにStaticファイルが集められます。

STATIC_URLはWEBサーバーがStaticファイルを見に行く場所を設定する項目だそうですが、「/static/」とされておりSTATIC_ROOTのパスと異なる点が個人的に理解できていません。STATIC_ROOTとSTATIC_URLの設定について調べると両方とも同じ「/static/」に設定されている例が多くみつかります。

HerokuにデプロイしたアプリケーションのStaticファイルのURLを確認してみると、/static/○○/□□/hogehoge.pngといった形になっていました。つまり、STATIC_ROOTの「staticfiles」には静的ファイルの実態が保存されており、STATIC_URLの「/static/」がサーバーとして公開されるディレクトリになっていることを確認しました。このあたりは個人的にHerokuに限らずサーバー関係の取り扱いについて知識が足りておらず理解できていないため、調査中です。

STATICFILES_DIRSはDjangoの個別アプリケーションに限らず共通で使うファイルを置くディレクトリを設定する項目のようです。こちらはSTATIC_ROOTにコピーされます。つまり、Herokuの設定に従うと「staticfiles」にコピーされます。

STATIC_URLの設定については以下の記事も参考になると思います。

https://kikuichige.com/10984/

500エラーの解決

結局のところ個人的に解決には至ったのですが、正直なところその理由については明確に理解できていません。

結論としてはsettings.pyからSTATICFILES_DIRSを削除することで500エラーが解消しました。

# Extra places for collectstatic to find static files.
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

これをHerokuデプロイ時に読み込まれる設定から削除したところ500エラーが解消し、アプリケーションが動作しました。

Herokuの環境を確認するために、heroku run bashを実行してHeroku上のstaticfiles(STATIC_ROOTで設定したディレクトリ)の中を確認すると確かにStaticファイルが保存されていました。

500エラーの解決についてネットで調べると以下の記事が出てきました。

404 Not Found

この記事ではSTATICFILES_DIRSがいらないとされています。

STATICFILES_DIRSはいらない。

https://www.mathpython.com/ja/django-debug-false/

また、以下の記事では直接STATICFILES_DIRSについては触れられていませんが、結果的にSTATICFILES_DIRSの設定が削除されています。

https://yukituna.com/2422/

結果として500エラーの解決には至りましたが、どうして解決できたか理解できていないため引き続き調査する予定です。

なお、HerokuはGitで管理されていないファイルは自動的に削除されるため、今回の解決に至った設定が誤っている恐れもあるため引き続き確認を行います。

コメント

タイトルとURLをコピーしました