Flask + SQLAlchemy + SQLite で作ったWebアプリをHerokuで公開しました



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つずつ意味を理解して問題が発生したときに原因をすぐに特定できるようにしたいです。

Previous
Next Post »

人気の投稿