2022年1月28日金曜日

Heroku で Python Flask で Postgres へ接続 (ローカル開発環境は Docker コンテナ)

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’ が表示される

0 件のコメント:

コメントを投稿