0
2

More than 1 year has passed since last update.

Flask × postgresql × Heroku でデプロイまでしたときの過程・備忘録・エラー対処まとめ

Last updated at Posted at 2022-05-30

はじめに

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はこんな感じです。

__init__.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
server.py
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

Procfileはweb: gunicorn <実行ファイル名 ※拡張子は含まない>:app --log-file=-というように記述します。gunicornとはHTTPサーバで、Herokuのドキュメントで使用が推奨されています。
今回の私の環境の場合は、

web: gunicorn server:app --log-file=-

というようになります。

  • requirements.txt

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

というようになりました。

  • runtime.txt

Pythonのランタイムバージョンを指定します。
私の環境では、このように記述しました。

runtime.txt
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に貼り付けてください。

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だとエラーが起きるのでコマンドプロンプトから実行する

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2