Heroku の Python Flask アプリの環境で Postgres への接続を試してみました。
一つの Flask アプリでコードを書き換えずにローカル環境で実行した場合はローカルの Postgres、ネット上の Heroku 環境で実行した場合は Heroku の Postgres に接続できることを確認しています。
ローカルの開発環境は Docker コンテナを一つ用意し、この中に Heroku CLI、Postgres を入れています。
Docker イメージ作成
Heroku CLI, Postgres 用の Docker イメージは Docker Hub の Postgres をベースにして dockerfile でごにょごにょして Heroku CLI のインストール等を行います。
dockerfile は以下の通りです。
FROM postgres
RUN apt update && apt -y upgrade
RUN apt update && apt -y upgrade
RUN apt install -y \
sudo \
curl \
wget \
unzip \
git \
byobu \
python3-pip \
libpq-dev
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*
RUN curl https://cli-assets.heroku.com/install.sh | sh
RUN useradd \
--create-home \
--groups sudo \
--shell /bin/bash \
worker
RUN echo 'worker:worker' | chpasswd
RUN su - worker -c 'mkdir /home/worker/Desktop'
Docker イメージをビルド
$ docker build --tag heroku-postgres:1 ./
Docker コンテナを開始
$ docker run \
-p 5000:5000 \
--name test-heroku-postgres \
-e POSTGRES_PASSWORD=mysecretpassword \
-d \
heroku-postgres:1
-
「
-p 5000:5000
」で Heroku ローカル開発環境 (heroku local web
) で公開する 5000 番ポートに外部のブラウザからアクセスできるようにしてます。 -
コンテナ開始時に Postgres が初期化されるようなので「
-e POSTGRES_PASSWORD=mysecretpassword
」環境変数でパスワードを指定しています。ローカルのとりあえずの環境なのでパスワードそのまま書いていますが、気になる場合は https://hub.docker.com/_/postgres の「Docker Secrets」あたりを読むとパスワードをファイルに書いてそのファイル名を指定することもできるようです。(試していないので本当にできるかわかりません) -
「
-d
」を指定しているのでシェルのコマンドプロンプトにすぐ戻り、「$ docker ps -a
」で確認するとバックグラウンドでコンテナが動いていることが確認できます。 -
PC 再起動時等、コンテナが停止している場合は以下でコンテナを起動できます。
$ docker container start test-heroku-postgres
起動しているコンテナで bash を実行して worker ユーザーになります。
$ docker exec -it test-heroku-postgres /bin/bash
# su - worker
$ cd Desktop/
以下、コンテナの中の bash で実行しています。
Flask アプリのスクリプトをダウンロード
Postgres に接続するテスト用の Python Flask スクリプトを Gist (https://gist.github.com/nezuppo/c36bbb4c1f81da348ba74e8ccf3001bf) に貼り付けています。
Gist からこのスクリプトをダウンロード
$ wget https://gist.github.com/nezuppo/c36bbb4c1f81da348ba74e8ccf3001bf/archive/e1df36533ba102fd1494e06d23398f6f3d7b891e.zip
- 別途新規で git init をする必要があるため、git clone ではなく wget で zip ファイルをダウンロードしています。
ダウンロードした zip を解凍してディレクトリに cd
$ unzip e1df36533ba102fd1494e06d23398f6f3d7b891e.zip
$ cd c36bbb4c1f81da348ba74e8ccf3001bf-e1df36533ba102fd1494e06d23398f6f3d7b891e/
ローカル開発環境で Flask アプリからローカルの Postgres に接続
localdb データベース作成
$ createdb -U postgres localdb
postgres ユーザーで localdb データベースを指定して psql 起動
$ psql -U postgres localdb
psql 内で testtable を作成してデータを挿入
localdb=# create table testtable(aaa text);
localdb=# insert into testtable values('test local');
localdb=# select * from testtable;
aaa
------------
test local
(1 row)
localdb=# exit
Python の必要なパッケージをインストール
$ sudo pip install -r requirements.txt
環境変数 DATABASE_URL で Postgres への接続情報を指定して heroku ローカル開発環境を起動
$ DATABASE_URL=postgresql://postgres@localhost/localdb \
heroku local web
ブラウザで http://localhost:5000/ を開くと Flask アプリが Postgres に接続し、インサートされた「test local
」をひっぱってきてブラウザに表示されます。
終了は ctrl-c
です。
ネット上の Heroku サイトの Flask アプリから Heroku 上の Postgres に接続
git の初期設定
$ git config --global user.email "worker@localdomain"
$ git config --global user.name "worker"
git を初期化
$ git init
.gitignore 作成
$ echo "__pycache__/" > .gitignore
ファイルを git に追加して commit
$ git add .
$ git commit -m "first commit"
Heroku にログイン
$ heroku login
Heroku アプリを作成
$ heroku create
Heroku Postgres をアドオン
$ heroku addons:create heroku-postgresql:hobby-dev
- 最初に
git init
しているので --app で Heroku アプリ名を指定する必要はありません
Heroku のアプリに Postgres がアドオンされたことを確認
$ heroku addons
Heroku Postges への接続 URL の確認
$ heroku config
Heroku Postgres に関する情報の確認
$ heroku pg
Heroku アプリにアドオンした Postgres (ローカルではなくリモート) に psql で接続
$ heroku pg:psql
psql 内で testtable を作成してデータを挿入
DATABASE=> create table testtable(aaa text);
DATABASE=> insert into testtable values('test remote');
DATABASE=> select * from testtable;
aaa
-------------
test remote
(1 row)
DATABASE=> exit
リモートが Heroku であることを確認
$ git remote
heroku
リモートに git push して Heroku アプリを初期化
$ git push heroku master
ブラウザでアクセスする URL を確認
$ heroku open
- 本来はブラウザを立ち上げるためのコマンドだが、Docker コンテナが CUI 環境のためブラウザが起動されず URL が表示されるので、これをブラウザにコピペして開く
- Postgres にインサートした ‘test remote’ が表示される