Python (Flask) + SQLAlchemy + SQLite で作ったWebアプリを公開するために Heroku を使いました。
初めてHerokuを使ったので手順を書き残しておきます。
今回の公開対象は下記で作成したWebアプリです。
*Heroku とは
PaaSのひとつで、クラウド環境でアプリケーションを実行するためのプラットフォームです。Heroku を使うことで自分で作ったWebアプリケーションを公開することができます。使用できる言語や拡張機能も多く用意されており、手軽に公開できるといった特徴があります。
使うためにはアカウントの登録が必要です。料金プランが複数用意されていますが、試すだけでしたら無料プランでも十分です。
*参考
*環境
- MacOS
- Python 3.6.3
- Flask 1.0.2
- heroku 7.24.1
- PostgreSQL 11.2
*Heroku アカウントの登録
下記サイトからアカウント登録をします。ターミナルで下記コマンドを実行して Heroku をインストールします。
CLI で Heroku の操作ができるようになります。
$ brew tap heroku/brew && brew install heroku
*PostgreSQLへの移行
Heroku では SQLite が使えないので PostgreSQL に移行します。ローカル環境に PostgreSQL をインストールします。
$ brew install postgresql
文字コードをUTF-8に変更してDBを初期化します。
コマンド実行後にメッセージが表示されますが無視して大丈夫です。
$ initdb /usr/local/var/postgres -E utf8
The files belonging to this database system will be owned by user "XXX".
This user must also own the server process.
The database cluster will be initialized with locale "ja_JP.UTF-8".
initdb: could not find suitable text search configuration for locale "ja_JP.UTF-8"
The default text search configuration will be set to "simple".
Data page checksums are disabled.
initdb: directory "/usr/local/var/postgres" exists but is not empty
If you want to create a new database system, either remove or empty
the directory "/usr/local/var/postgres" or run initdb
with an argument other than "/usr/local/var/postgres".
PostgreSQL が正常にインストールされているか確認します。
バージョンが表示されれば大丈夫です。
$ postgres --version
postgres (PostgreSQL) 11.2
PostgreSQL サーバーを起動します。
$ postgres -D /usr/local/var/postgres
2019-05-01 11:56:06.076 JST [33919] LOG: listening on IPv4 address "127.0.0.1", port 5432
2019-05-01 11:56:06.076 JST [33919] LOG: listening on IPv6 address "::1", port 5432
2019-05-01 11:56:06.077 JST [33919] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432"
2019-05-01 11:56:06.096 JST [33920] LOG: database system was shut down at 2019-05-01 11:54:24 JST
2019-05-01 11:56:06.104 JST [33919] LOG: database system is ready to accept connections
^C2019-05-01 11:56:32.668 JST [33919] LOG: received fast shutdown request
2019-05-01 11:56:32.669 JST [33919] LOG: aborting any active transactions
2019-05-01 11:56:32.671 JST [33919] LOG: background worker "logical replication launcher" (PID 33926) exited with exit code 1
PostgreSQL サーバーを起動した状態で、別ウィンドウでターミナルを起動し下記コマンドを実行します。
flasknote
という名前のデータベースが作成されます。$ createdb flasknote
## データベース一覧を表示
$ psql -l
SQLAlchemy で PostgreSQL を使えるようにするため、Python の PostgreSQL 用ドライバである psycopg2 をインストールします。
$ pip install psycopg2
PostgreSQL でローカル環境にテーブルを作成します。
プロジェクト直下でPythonインタプリタを起動し、下記コマンドを順番に実行します。
create_app()
を実行後にメッセージが表示されますが無視して大丈夫です。$ python
>>> from flaskblog import create_app, db
>>> app = create_app()
/Users/XXX/Python/Flask_Blog/env/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py:794: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning.
'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
>>> app.app_context().push()
>>> db.create_all()
Heroku で動かす際ににPython製のWSGIサーバー
gunicorn
を使う必要があるので、Heroku にデプロイする前にgunicorn
で起動確認をします。gunicorn
をインストールしてサーバーを起動します。$ pip install gunicorn
$ gunicorn run:app
下記URLにアクセスしてWebアプリケーションが表示されれば大丈夫です。
http://127.0.0.1:8000
*Herokuデプロイに必要なファイルを作成
プロジェクト直下にrequirements.txt
を作成します。これが Heroku サーバー上で
pip install
されます。下記コマンドを実行します。
$ pip freeze > requirements.txt
プロジェクト直下に
Procfile
を新規作成して下記内容を書きます。gunicorn
を起動するときにこのコマンドが実行されます。gunicorn
コマンドの引数は{ファイル名}:{インスタンス名}
になるので、適宜書き換えてください。web: gunicorn run:app
プロジェクト直下に
runtime.txt
を新規作成します。使用するPythonのバージョンを指定します。
python-3.6.3
*Herokuにデプロイ
下記コマンドを実行すると Heroku に新しくアプリを作成することができます。アプリ名は他で使われている名前と重複しているとエラーになるので、数値など組み合わせて被らない名前にする必要があります。
アプリ名を省略すると、適当な名前でアプリを作成してくれます。
$ heroku create {アプリ名}
Heroku で PostgreSQL を使うために、アドオンを追加します。
$ heroku addons:add heroku-postgresql
Creating heroku-postgresql on ⬢ calm-beach-62772... free
Database has been created and is available
! This database is empty. If upgrading, you can transfer
! data from another database with pg:copy
Created postgresql-curved-92847 as DATABASE_URL
Use heroku addons:docs heroku-postgresql to view documentation
Heroku 上でDBに接続するため、データベースURIを変更します。
SQLALCHEMY_DATABASE_URI
の値を下記に修正します。今回は
config.py
で値を定義していますが、設定しているファイルは構成によって異なります。<config.py>
class Config:
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'postgresql://localhost/flasknote'
...
下記コマンドを実行して Heroku にデプロイします。
$ git push heroku master
*HerokuのDBにテーブルを作成
このままだとHeroku サーバーのDBにテーブルが作成されていない状態なので、Pythonインタプリタを使ってテーブルを作成します。ローカルのターミナルで下記コマンドを実行し、Heroku 上のPythonインタプリタを起動します。
$ heroku run python
Heroku 上のデータベースが PostgreSQL になっているか確認します。
環境変数
DATABASE_URL
の値を確認します。>>> import os
>>> a = os.environ.get('DATABASE_URL')
>>> print(a)
postgres://wbxnpvigpfmzwc:4cfc6cf9074b4aef1a8dbb056d21795710d87287727ecae82bb3a8a20e81bb57@ec2-54-197-239-115.compute-1.amazonaws.com:5432/d6pj7po9639r12
PostgreSQL が使われている状態であることを確認したら、テーブルを作成します。
インタプリタで下記コマンドを実行し、
db.create_all()
でテーブルを作成します。>>> from flaskblog import create_app, db
>>> app = create_app()
/app/.heroku/python/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py:794: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning.
'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
>>> app.app_context().push()
>>> db.create_all()
インタプリタを終了し、下記コマンドを実行するとWebアプリをブラウザで開いてくれます。
$ heroku open
ブラウザに作成したWebアプリケーションが表示されれば正常に起動できています。
起動できなかった場合は、下記コマンドを実行してログからエラーの原因を調査します。
$ heroku logs --tail
*所感
Heroku で SQLite が使えないことを知るのに時間がかかり、正常に起動するまでに時間がかかってしまいました。Heroku も初めて使いましたが
gunicorn
も初めて使ったので勉強になりました。環境設定といったことは苦手なので、1つずつ意味を理解して問題が発生したときに原因をすぐに特定できるようにしたいです。Sign up here with your email
ConversionConversion EmoticonEmoticon