3
2

More than 1 year has passed since last update.

fly.ioにPython(Flask) WebAppをデプロイ→git pushで自動デプロイ

Last updated at Posted at 2022-10-16

はじめに

自作Web Appをherokuで運用しようとしていたのですが、herokuの料金プランが変更されるとのことなので急遽fly.ioを試してみました。
fly.ioの公式サイトのマニュアルを参考に作業した手順を自分用に簡単にまとめます。

作業手順

  1. 公式サイトからGitHubアカウントでサインイン
  2. こちらを参考に、Pythonのサンプルプロジェクトをcloneしてデプロイする
    flyctlのインストールはこちらを参考
  3. こちらを参考に、以下を実施
    3-1. 自動デプロイしたいGitHubのリポジトリを表示し、設定を開く
    3-2. Secrets → Actionsから新しいシークレットを作成する
      名前:FLY_API_TOKEN
      トークン:flyctl auth tokenで取得した文字列
    3-3. .gitignoreにfly.tomlがある場合、削除しておく
    3-4. ./.github/workflows/main.ymlファイルを作成し、内容をコピペして保存する
    3-5. 変更をcommitし、pushすると自動デプロイされる

※マニュアルのステップ1, 5は不要(既にサンプルプロジェクトをcloneしており、かつ本記事用に新しいリポジトリを作成したため)
 代わりに以下を実施

公式のサンプルプロジェクトをclone → .gitディレクトリ削除 → git init → git remote add <自分のリポジトリ> → git push origin master

※マニュアルのステップ7は不要(flyctl launch実行時にfly.tomlファイルが作成されるため)

DB追加

今回はpsycopg2を使ってDBに接続することにしました。

  1. hellofly.pyを以下に変更
    ※本来は接続情報ベタ書きは良くないですが、今回はお試しなのでベタ書きしました
from flask import Flask, render_template
import psycopg2

app = Flask(__name__)

connector = psycopg2.connect('postgresql://{user}:{passwd}@{host}:{port}/{dbname}'.format(
  user="<launchした際に表示された情報の「Username」>",
  passwd="<launchした際に表示された情報の「Password」>",
  host="<launchした際に表示された情報の「Hostname」>",
  port="<launchした際に表示された情報の「Proxy Port」>",
  dbname="postgres"
))

@app.route('/')
def hello():
    cursor = connector.cursor()
    cursor.execute("SELECT version();")
    version = cursor.fetchone()
    return render_template('hello.html', version=version)

2.htmlを以下に変更

<!DOCTYPE html>
<html lang="jp">
  <head>
  </head>
  <body>
    <h1>Hello from Fly</h1>
    <p>{{version}}</p>
  </body>
</html>

3.requirements.txtを以下に変更

click==8.1.3
Flask==2.2.2
gunicorn==20.1.0
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.1
Werkzeug==2.2.2
psycopg2-binary==2.9.3 ←追加

ここまでで以下画面が表示できます。
image.png

ハマったポイント

psycopg2をインストールしようとするとデプロイ時にエラーになった

GitHub Actionsでエラーになっていた

エラー
Collecting psycopg2==2.9.3
  Downloading psycopg2-2.9.3.tar.gz (380 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 380.6/380.6 kB 43.5 MB/s eta 0:00:00
  Preparing metadata (setup.py): started
  Preparing metadata (setup.py): finished with status 'error'
  error: subprocess-exited-with-error
  
  × python setup.py egg_info did not run successfully.
  │ exit code: 1
  ╰─> [25 lines of output]
      /layers/paketo-buildpacks_cpython/cpython/lib/python3.10/site-packages/setuptools/config/setupcfg.py:508: SetuptoolsDeprecationWarning: The license_file parameter is deprecated, use license_files instead.
        warnings.warn(msg, warning_class)
      running egg_info
      creating /tmp/pip-pip-egg-info-fgdgnfc0/psycopg2.egg-info
      writing /tmp/pip-pip-egg-info-fgdgnfc0/psycopg2.egg-info/PKG-INFO
      writing dependency_links to /tmp/pip-pip-egg-info-fgdgnfc0/psycopg2.egg-info/dependency_links.txt
      writing top-level names to /tmp/pip-pip-egg-info-fgdgnfc0/psycopg2.egg-info/top_level.txt
      writing manifest file '/tmp/pip-pip-egg-info-fgdgnfc0/psycopg2.egg-info/SOURCES.txt'
      
      Error: pg_config executable not found.
      
      pg_config is required to build psycopg2 from source.  Please add the directory
      containing pg_config to the $PATH or specify the full executable path with the
      option:
      
          python setup.py build_ext --pg-config /path/to/pg_config build ...
      
      or with the pg_config option in 'setup.cfg'.
      
      If you prefer to avoid building psycopg2 from source, please install the PyPI
      'psycopg2-binary' package instead.
      
      For further information please check the 'doc/src/install.rst' file (also at
      <https://www.psycopg.org/docs/install.html>).
      
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

error: exit status 1
ERROR: failed to build: exit status 1
Error failed to fetch an image or build from source: executing lifecycle: failed with status code: 51


Error: Process completed with exit code 1.

→psycopg2-binaryを使うことで回避できた
また、Dockerfileからのデプロイならpsycopg2でも可能らしい(試していない)
https://community.fly.io/t/cant-install-psycopg2-due-to-missing-pg-config/7382/3

connectorのdbnameに何を設定すればいいのかわからない

→flyctlからpostgresに入ってDB名を確認した

flyctl postgres connect -a <db名>
\l
   Name    |   Owner    | Encoding |  Collate   |   Ctype    |     Access privileges
-----------+------------+----------+------------+------------+-------------------------------------------
 postgres  | flypgadmin | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | flypgadmin | UTF8     | en_US.utf8 | en_US.utf8 | =c/flypgadmin + flypgadmin=CTc/flypgadmin
 template1 | flypgadmin | UTF8     | en_US.utf8 | en_US.utf8 | =c/flypgadmin + flypgadmin=CTc/flypgadmin
(3 rows)
\q

CRUD(と言いつつCreateだけ)

1.hellofly.pyを以下に変更

from flask import Flask, render_template
import psycopg2

app = Flask(__name__)

connector = psycopg2.connect('postgresql://{user}:{passwd}@{host}:{port}/{dbname}'.format(
  user="<launchした際に表示された情報の「Username」>",
  passwd="<launchした際に表示された情報の「Password」>",
  host="<launchした際に表示された情報の「Hostname」>",
  port="<launchした際に表示された情報の「Proxy Port」>",
  dbname="postgres"
))

@app.route('/')
def hello():
    cursor = connector.cursor()
    cursor.execute("SELECT version();")
    version = cursor.fetchone()

    cursor.execute("SELECT * FROM test;")
    select = cursor.fetchall()
    return render_template('hello.html', version=version, select=select)

@app.route('/insert')
def insert():
    cursor = connector.cursor()
    cursor.execute("INSERT INTO test(name) VALUES ('hoge');")
    connector.commit()
    return redirect('./')

2.htmlを以下に変更

<!DOCTYPE html>
<html lang="jp">
  <head>
  </head>
  <body>
    <h1>Hello from Fly</h1>
    <p>{{version}}</p>
    <br />
    <p>{{select}}</p>
    <a href="./insert">insert</a>
  </body>
</html>

「insert」リンクをクリックするとレコードが追加される
image.png

image.png

insertができれば同じ要領でupdate, deleteも可能です。

おわりに

本記事ではここまで(fly.ioに環境構築 + デプロイ + postgreDB使用)とします。
これで自作WebAppを移行する準備ができました。
(まだ開発終わってないですが...)

開発終わってデプロイしたらまた記事を書きたいと思います。

3
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
3
2