はじめに
Flaskの勉強で簡単なアプリを作ったので、Herokuにデプロイしてみました。手順も忘れてしまいそうなので備忘録ついでに書き記しておきます。
前提
- herokuアカウントを持っていること
- herokuコマンドが使えること
- gitコマンドが使えること
ローカルで開発
まずはPythonでアプリを作りましょう。
今回はPostgreSQLと連携してSQLAlchemyを使ってテーブルのデータを表示するアプリを作りました。
ファイル構成はこんな感じです。
─
│ server.py
│
└─flask_app
│ config.py
│ __init__.py
│
├─models
│ data.py
├─static
│
├─templates
│ index.html
├─views
views.py
__init__.pyとserver.pyはこんな感じです。
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_object('flask_app.config')
db = SQLAlchemy(app)
from flask_app.views import views
from flask_app import app
if __name__ == '__main__':
app.run()
python server.py
を実行することでwebアプリケーションサーバが起動し、デフォルトではループバックアドレスの5000番ポートにアクセスすることで見ることができます。ちなみに、デバッグモードをオンにしているとホットリロードに対応するので便利です。
また、今回はSQLAlchemyのORMを利用して、ローカルのPostgreSQLサーバからデータを取得しています。
デプロイ準備
Herokuを利用することで無料でウェブアプリケーションをデプロイすることができます。なお、無料版だと様々な制限があるので、詳しくはこちらを参照してください。普通に自分の製作物を一時的に公開したいだけなら無料版で十分だと思います。また、アドオンを使用することで新たなDBサーバやメールサーバ、モニタリングなどができるようになりますが、今回使用するHeroku Postgresは無料で使用することができます。
1.デプロイ用のファイルを追加
まずはプロジェクトをHerokuに上げるためのファイルを用意しましょう。
必要なものは以下の3つのファイルです。なお、プロジェクトのフォルダと並列な場所に配置する必要があります。
- Procfile
⇒ウェブアプリがどのようなコマンドで実行するかを示す指示書のようなもの - requirements.txt
⇒実行に必要なライブラリとバージョンを指定 - runtime.txt
⇒Pythonのランタイムバージョンを指定
Procfileはweb: gunicorn <実行ファイル名 ※拡張子は含まない>:app --log-file=-
というように記述します。gunicornとはHTTPサーバで、Herokuのドキュメントで使用が推奨されています。
今回の私の環境の場合は、
web: gunicorn server:app --log-file=-
というようになります。
requirement
ではなくrequirements
なので気を付けましょう。中身はライブラリ群とバージョンが記述されます。。
デプロイ後のHTTPサーバはgunicornを使用するので、pip install gunicorn
をするか、直接requirements.txtに書き込んでください。
コマンドでpip freeze > requirements.txt
とすればライブラリ情報が書き込まれます。
手動で必要なライブラリを指定したい場合は、<ライブラリ名>==<バージョン名>
と記述してください。なお、依存ライブラリの関係を調べるならpipdeptreeを使用すると便利です。
ちなみに私の環境では、
Flask==2.1.0
Flask-SQLAlchemy==2.5.1
Jinja2==3.1.1
SQLAlchemy==1.4.36
click==8.1.3
colorama==0.4.4
importlib-metadata==2.0.0
zipp==3.2.0
itsdangerous==2.1.2
MarkupSafe==2.1.1
Werkzeug==2.1.2
greenlet==1.1.2
gunicorn==20.0.4
psycopg2==2.9.3
psycopg2-binary==2.9.3
というようになりました。
Pythonのランタイムバージョンを指定します。
私の環境では、このように記述しました。
python-3.7.13
ここで気を付けるべき点が2点あります。一つはPython
ではなくpython
であることで、もう一つはバージョンの指定です。
remote: -----> Using Python version specified in runtime.txt
remote: ! Requested runtime (python-3.7.5) is not available for this stack (heroku-20).
remote: ! Aborting. More info: https://devcenter.heroku.com/articles/python-support
remote: ! Push rejected, failed to compile Python app.
remote:
remote: ! Push failed
もしデプロイ時にこのようなエラーログが出たら、ランタイムバージョンの指定が間違っています。こちらの"supported runtimes"からサポートされているバージョンを指定してください。
ちなみに現在のサポートは、
python-3.10.4 on all supported stacks
python-3.9.13 on all supported stacks
python-3.8.13 on Heroku-18 and Heroku-20 only
python-3.7.13 on Heroku-18 and Heroku-20 only
となっています。
2.Heroku上にアプリを作成
heroku create <アプリ名>
でheroku上にアプリを作成することができます。
なお、createした時点でリモートリポジトリにherokuのリポジトリが登録されるので、ここへプッシュするとデプロイができるようになります。
heroku create flask-app
3.HerokuにPostgreSQLのアドオンを追加
今回はPostgresを使ってデータを操作しているので、PostgresのサーバをHerokuアプリ上で連携させる必要があります。
アドオンの追加は、heroku addons:create heroku-postgresql:<PLAN_NAME>
を実行することで追加できます。PLAN_NAMEにはhobbyやstandardなどがありますが、今回のように試しに上げてみる程度でしたら一番下のhobbyで十分です。詳しいプラン内容はこちらをご覧ください。
heroku addons:create heroku-postgresql:hobby-dev
4.Heroku上のPostgresにデータを移行
今回はローカルの開発で使用した、PostgresのデータをHeroku上のPostgresに移したいと思います。
ローカルでバックアップファイルを作成してHeroku postgresでインポートする方法などもありますが、今回はpg:push
を使用したいと思います。
SET PGUSER=postgres
heroku pg:push postgres DATABASE_URL --app flask-app
なお、DATABASE_URLの変更や新たなDBを追加したい場合はHerokuの管理画面から簡単にできます。
次に、ソースコードのconfig.pyで設定しているpostgresのURIをローカルからHeroku postgresのものに変更します。
そのためにはまずHeroku postgresのURIを確認しましょう。Herokuの管理画面から、Setting⇒config varsを開き、DATABASE_URLの横のURLをコピーします。そしてconfig.pyに貼り付けてください。
SQLALCHEMY_DATABASE_URI = 'postgresql://xxxxxx'
なお、ここで注意点があります。管理画面では最初がpostgres
になっているかと思いますが、ここをpostgresql
に直してください。ここをそのままにするとsqlalchemy.exc.NoSuchModuleError: Can’t load plugin: sqlalchemy.dialects:postgres
というエラーが出ます。原因は、SQLAlchemyがpostgresのサポートを削除したためらしいです。
これでHeroku postgresの設定が完了しました。あとはデプロイするだけです。
5.Gitからアプリケーションをデプロイ
リモートリポジトリのmasterブランチにデプロイすることでアプリが動きます。
git init
git .
git commit -m "first commit"
git push heroku master
これでデプロイ完了です。
heroku open
を実行して実際に確認してみましょう。
もし、期待通りに反映されていない場合はheroku logs
でエラーログを確認してみてください。
所感
今回初めてHerokuを使用してみましたが、無料でいろいろとできるので素晴らしいサービスだと感じました。
特にデプロイまでの手順が簡単なことや管理画面のUIがシンプルで使いやすい面も良いと思います。
追記
pg:pushはPowerShellだとエラーが起きるのでコマンドプロンプトから実行する