はじめに
自作Web Appをherokuで運用しようとしていたのですが、herokuの料金プランが変更されるとのことなので急遽fly.ioを試してみました。
fly.ioの公式サイトのマニュアルを参考に作業した手順を自分用に簡単にまとめます。
作業手順
- 公式サイトからGitHubアカウントでサインイン
-
こちらを参考に、Pythonのサンプルプロジェクトをcloneしてデプロイする
flyctlのインストールはこちらを参考 -
こちらを参考に、以下を実施
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に接続することにしました。
- 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 ←追加
ハマったポイント
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」リンクをクリックするとレコードが追加される
↓
insertができれば同じ要領でupdate, deleteも可能です。
おわりに
本記事ではここまで(fly.ioに環境構築 + デプロイ + postgreDB使用)とします。
これで自作WebAppを移行する準備ができました。
(まだ開発終わってないですが...)
開発終わってデプロイしたらまた記事を書きたいと思います。