秋の田のかりほの庵の苫を荒みわがころも手は露に濡れつつ
Advent Calendar 2022 50日目1の記事です。
I'm looking forward to 12/25,2022
私のAdvent Calendar 2022 一覧。
はじめに
fly.ioの話を書きます。
はじめて使ってみました。
ちょっと変わり種? の
「Deploy Your Application via Dockerfile」の例を示します。
What's fly.io ?
Run your full stack apps (and databases!) all over the world. No ops required.
PaaSに分類されるサービスだとおもいます。
軽く使ってみたくらいですが、使いやすいです。
Phoenixアプリとの相性が抜群によさそうです。
Phoenixアプリをデプロイする例
@koga1020 さんの記事をオススメしておきます。
Deploy Your Application via Dockerfile
題材はPythonを使ったSlackアプリにします。
「Bolt 入門ガイド」で紹介されているプログラムをそのまま使います。
Slack側の設定は、Bolt 入門ガイドの通りに設定しているものとします。
ソースコード
以下を用意します。
こちらのPythonのプログラムは、Slackアプリが追加されたチャンネルでhello
という文字列を含む書き込みがされると、Hey there <@投稿者> !
というふうに挨拶を返してくれるbotです。
「Bolt 入門ガイド」の通りのソースコードです。
import os
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
# ボットトークンとソケットモードハンドラーを使ってアプリを初期化します
app = App(token=os.environ.get("SLACK_BOT_TOKEN"))
# 'hello' を含むメッセージをリッスンします
# 指定可能なリスナーのメソッド引数の一覧は以下のモジュールドキュメントを参考にしてください:
# https://slack.dev/bolt-python/api-docs/slack_bolt/kwargs_injection/args.html
@app.message("hello")
def message_hello(message, say):
# イベントがトリガーされたチャンネルへ say() でメッセージを送信します
say(f"Hey there <@{message['user']}>!")
# アプリを起動します
if __name__ == "__main__":
SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]).start()
同じフォルダにDockerfileを用意します。
FROM python:3
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD [ "python", "./app.py" ]
アカウント作成
私は、 https://fly.io/ サイト上でつくりました。
GitHubアカウントで連携しました。
Installing flyctl
に従って、インストールをしてflyctl
コマンドが使えるようにします。
flyctl
コマンドでの操作
flyctl
コマンドで操作していきます。
ログイン
まずはログインします。
$ flyctl auth login
初期設定
$ flyctl launch
? Overwrite "/Users/awesome/first-bolt-app/Dockerfile"? (y/N)
にはN
を答えます。
? Would you like to setup a Postgresql database now?
にはN
を答えます。
そのほかの設問は、デフォルトのままエンターでよいでしょう。
お好みで変更してください。
以下のようなfly.toml
ファイルが自動的につくられます。
# fly.toml file generated for rough-paper-5532 on 2022-02-19T23:03:26+09:00
app = "rough-paper-5532"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
[env]
PORT = "8080"
[experimental]
allowed_public_ports = []
auto_rollback = true
[[services]]
http_checks = []
internal_port = 8080
processes = ["app"]
protocol = "tcp"
script_checks = []
[services.concurrency]
hard_limit = 25
soft_limit = 20
type = "connections"
[[services.ports]]
handlers = ["http"]
port = 80
[[services.ports]]
handlers = ["tls", "http"]
port = 443
[[services.tcp_checks]]
grace_period = "1s"
interval = "15s"
restart_limit = 0
timeout = "2s"
[[statics]]
guest_path = "/app/public"
url_prefix = "/static/"
このアプリでは、ソケットモードで動作させますので不要な設定は消しておきます。
これをしないと、次回のデプロイ時にヘルスチェックに引っかかるなどして、新しいほうがうまくデプロイされないなどの動きになります。
# fly.toml file generated for rough-paper-5532 on 2022-02-19T23:03:26+09:00
app = "rough-paper-5532"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
環境変数の設定
環境変数を2つ設定しておきます。
SLACK_BOT_TOKEN
SLACK_APP_TOKEN
それぞれの環境変数の意味は、「Bolt 入門ガイド」をご参照ください。
このアプリ特有の環境変数です。
$ flyctl --app rough-paper-5532 secrets set SLACK_BOT_TOKEN="xoxb-xxx"
$ flyctl --app rough-paper-5532 secrets set SLACK_APP_TOKEN="xapp-xxx"
--app rough-paper-5532
の部分は、ご自身のアプリ名で置き換えてください。
deploy
いよいよデプロイタイムです。
Dockerをローカルで動かしておいてください。
If you have Docker running locally, it builds it on your machine. If not, it builds it on a Fly build machine.
ローカルマシンでビルドして、fly.ioにイメージをPushしているとのことです。
$ flyctl deploy --detach
--detach
フラグの意味は
Return immediately instead of monitoring deployment progress
です。
ヘルプは、flyctl deploy --help
で確認できます。
Wrapping up
fly.ioのドキュメントの中から、ちょっと変わり種? の「Deploy Your Application via Dockerfile」の例を示しました。
今回はPythonで作ったSlackアプリにしましたが、ElixirのBanditを利用して作ったSlackアプリ、LINEアプリを同じ要領で動かせるとおもいます。
今後やってみます。
追伸
以下は、ハマったこととしてそのまま残しておきます。
すでにfly.tomlを書き換えることで解決することは確認しておりまして、記事本文には反映済みです。
app.py
を変更して、flyctl deploy
すると変更内容がfly.ioに飛んでいるのですが、以下の挙動を確認しました。
- たまに古いDockerコンテナのほうがまだ動いている
- しばらくそのまま待っていると、新しいDockerコンテナのほうが完全に止まって、古いDockerコンテナのほうの動きをする
$ flyctl status
Instances
ID PROCESS VERSION REGION DESIRED STATUS HEALTH CHECKS RESTARTS CREATED
dccb1dc2 app 6 ⇡ sin(B) run running 1 total, 1 critical 0 2m31s ago
3af1fa4b app 2 nrt run running 1 total, 1 critical 1 35m8s ago
一時的に新らしいコンテナと古いコンテナが動いているようです。
VERSION 6
のほうに切り替わってくれればいいのですが、このまましばらく待つと、VERSION 6
がいなくなります。
回避策は、適当な環境変数を追加することです。
$ flyctl --app rough-paper-5532 secrets set HOGE="hoge"
一応、これで最新のほうの動きに寄りました
追伸の追伸 ーー Troubleshooting your Deployment
Troubleshooting your Deploymentを読んでみました。
なんとなくですが、ヘルスチェックに引っかかって新しいほうが停止されていたようです。
このアプリはhttp(s)は使っていないので不要な設定をfly.toml
から消しておきます。
これで、fly deploy
で最新内容がうまくデプロイされるようになりました。
# fly.toml file generated for rough-paper-5532 on 2022-02-19T23:03:26+09:00
app = "rough-paper-5532"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
ヨシヨシ、知見がたまった。