Django Girls Tutorial: Extensions内の"Herokuにデプロイしよう"の項にて、記載通りに行ってもうまくいかず四苦八苦したので、ケースとして残しておきたいと思います。
Herokuにデプロイしよう(PythonAnywhereだけでなく)
##Herokuへデプロイ時にエラー
チュートリアル通りに進めHerokuへデプロイすると以下のようにエラー。
Requested runtime (python-3.6.4) is not available for this stack (heroku-20).
エラーメッセージ通りに受け取るとpythonのバージョンが対応していない?
###サポートするpythonのバージョンをインストールする
Herokuのサポートページを確認すると以下のようにあるので、3.7.4をインストールしてみる。
python-3.7.4 (すべてのランタイムスタック)
python-3.6.9 (すべてのランタイムスタック)
python-2.7.16 (すべてのランタイムスタック)
runtime.txtの記述も変更することを忘れずに。
python-3.7.4
先頭文字を大文字にしたり、ハイフンを忘れると認識されないので注意。
結果はNG
Requested runtime (python-3.7.4) is not available for this stack (heroku-20).
バージョンは変わったが、何故かサポートされないと変わらず。
サポートページではすべてのランタイムスタックをサポートと書かれていたのに...
###Whitenoiseを疑う
Herokuを利用する際にWhitenoiseというMiddlewareを使用する。
ただ、正常に利用するためには一部記述を書き換えなければいけない様なので修正する。
STATIC_ROOT
に'staticfiles'
を追加。
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MIDDLEWARE
に'whitenoise.middleware.WhiteNoiseMiddleware',
を追加。
django.middleware.security.SecurityMiddleware'
の後、かつ他のMIDDLEWAREより前に記述した方がよいそうです。
なので↓こんな感じ。
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
# ...
]
結果はやはりNG
###Herokuのスタックの問題?
今回作成したAppはスタック20だった。
サポートページではスタックによってサポートされるバージョンが違うことがありそう。
3.7.4はすべてのスタックをサポートしていると記載はされているが、
スタック20が3.7.4をサポートしているかどうかの記述を見つけることができなかった。
と思ったら、日本語ページでは3.7.4はすべてのスタックでサポートと記載されているのに、英語ページでは書いてあることが違うじゃないか!
Heroku Python Support | Heroku Dev Center
どうやらスタック20は3.7.4には対応していない様子。
ということでスタック18ならサポートしているかもということでスタック18でAppを作成してみることに。
最新スタックへのアップグレード | Heroku Dev Center
heroku create
の後に--remote heroku-18 --stack heroku-18
とスタック番号を指定することで、任意のスタックでAppを作成できる模様。
$ cd <yourcodedirectory>
$ heroku create --remote heroku-18 --stack heroku-18 <your app name with heroku-18 appended>
結果、スタック18のAppにデプロイしたところ成功!!
ただし、別のエラーが発生。
アプリケーションをアップデートするか、もしくはdisableにしろとのこと。
remote: ! Error while running '$ python manage.py collectstatic --noinput'.
remote: See traceback above for details.
remote:
remote: You may need to update application code to resolve this error.
remote: Or, you can disable collectstatic for this application:
remote:
remote: $ heroku config:set DISABLE_COLLECTSTATIC=1
###collectstaticの設定を見直し
エラーの内容は静的assetの設定のようだが、前述のWhitenoiseの設定と、collectstaticの機能が勝手にactiveになるそう。
これを最適化するかdisableにすることが必要のようで、一旦はよくわからないのでdisableにすることとした。必要なら後で調べよう。
Django and Static Assets | Heroku Dev Center
$ heroku config:set DISABLE_COLLECTSTATIC=1
###migrateしたらmoduleが見つからない!?
改めてデプロイするために事前にcollectstatic
コマンドとmigrate
コマンドを実行。
$ python manage.py collectstatic
$ python manage.py migrate
すると、今度はmoduleが見つからないエラー
ModuleNotFoundError: No module named 'dj_database_url'
これは仮想環境で実行していたにもかかわらず、pip
でインストールしていたからと判明。
改めてpipenv
でインストール。他にもいくつかpip
でインストールされていたものがあったので、それらもインストールしなおし。
これで、モジュール見つからないエラーも解消。
$ pipenv install dj-database-url
この後に再度デプロイを実行し、ようやく成功!!
お疲れさまでした。
###Webにアクセスするもアプリケーションエラー
ようやくデプロイ成功したのでWebから早速アクセスしてみたけどアプリケーションエラー。
heroku logs --tail
でログを確認したが原因はよくわからず。
at=error code=H10 desc="App crashed" method=GET path="/"
これについては調査中...
(1/30追記:)
エラー内容は以下。
gunicorn
が見つからない的なエラーを吐いているので、これも仮想環境にモジュールがインストールされていないことが原因?
2021-01-29T15:34:05.223661+00:00 heroku[web.1]: State changed from crashed to starting
2021-01-29T15:34:10.461232+00:00 heroku[web.1]: Starting process with command `gunicorn mysite.wsgi --log-file -`
2021-01-29T15:34:13.054050+00:00 app[web.1]: bash: gunicorn: command not found
2021-01-29T15:34:13.103594+00:00 heroku[web.1]: Process exited with status 127
2021-01-29T15:34:13.145907+00:00 heroku[web.1]: State changed from starting to crashed
なので、改めて仮想環境にインストール。
whitenoise
も同様のエラーだったため、それもまとめて。
$ pipenv install gunicorn
$ pipenv install whitenoise
これで、もう一度Herokuへpush
し、migration
を実行したところ、無事改善。
エラーなくWebページが表示された!
##まとめ
根本原因はHerokuの最新のスタック20では、python3.7.4に対応していないことでした。
このスタック20は2020/4にリリース?されているようで比較的新しいみたいです。
そのためかスタックによるサポートの違いについて言及されている記事がなかったので同じように困っている方に届けばいいいなと思い記事にしてみました。
もし、間違っていることなどあればご指摘いただけると幸いです。