327 lines
11 KiB
Markdown
327 lines
11 KiB
Markdown
+++
|
||
date = "2022-08-27"
|
||
tags = ["heroku","fly"]
|
||
title = "herokuからfly.ioへの移行"
|
||
slug = "fly-heroku"
|
||
+++
|
||
|
||
herokuのplan:free(hobby)が廃止され、`mo/$31`になるので、[heroku](https://heroku.com/)から[fly.io](https://fly.io/)へ移行を考えています。
|
||
|
||
> Heroku Dynos starts at $7/month, Heroku Data for Redis® starts at $15/month, Heroku Postgres starts at $9/month.
|
||
|
||
https://blog.heroku.com/next-chapter
|
||
|
||
herokuのこれまでの評価は、素晴らしかったです。感謝しかありません。ありがとう!
|
||
|
||
### fly.io plan:free(hobby)
|
||
|
||
クレジットカードを登録するとplan:hobbyが使えるようになります。クレジットカードはできればVプリカ(visaプリペイドカード)などを使用するようにしてください。登録できない場合に通常のクレジットカードで登録するしかありません。このへんは未検証です。
|
||
|
||
> Add a payment method to get even more free allowances.
|
||
>
|
||
> VM: shared-cpu 2,340 hours per month Run 3 shared-cpu-1x VMs with 256MB RAM full time.
|
||
> Volumes 3GB Provision 3GB of persistent volumes for permanent storage
|
||
> Bandwidth 160GB per month See outbound data transfer for regional breakdown
|
||
> Anycast IPs Unlimited IPv6, 1 IPv4 per active app Additional IPv4 addresses are $2 per month
|
||
> Certificates 10 active certificates Add 10 certificates to your apps
|
||
|
||
- dyno : 2,340
|
||
|
||
- ram : 256M
|
||
|
||
- strage(volume) : 3G
|
||
|
||
https://fly.io/docs/about/pricing/
|
||
|
||
fly.ioはかなりherokuを意識しているようで、cliもありますので、herokuと同じように使いやすいと思いました。
|
||
|
||
herokuからの移行は[こちら](https://fly.io/launch/heroku)から自動で移行するツールがあります。が、これでうまくいくとは思っていません。
|
||
|
||
注意点としては以下になります。
|
||
|
||
- herokuとfly.ioで使うメールアドレスを同一のものにすること
|
||
|
||
これを行わないとfly.ioでherokuのメールアドレスからアカウントが作成された上で、appをdeployします。この際、アカウントにはクレジットカードの登録も必要です。あらかじめfly.ioで作成している場合、そのアカウントは使われません。
|
||
|
||
fly.ioの`launch/heroku`を使う際はherokuとfly.ioで使うメールアドレスを同一のものにしておきましょう。
|
||
|
||
さて、ではherokuからの移行ツールが動作するかというと、当然ですが移行ツールでは正常にdeployが完了しませんでした。
|
||
|
||
したがって、docsを読んで最初からfly.io用にdeployできる構成を作らなければなりません。
|
||
|
||
### mastodon
|
||
|
||
> ここではfly.ioでmastodonを正常に動作させるまでをやります
|
||
|
||
fly.ioでmastodonを動かす場合、(1)memory:512Mにすること、(2)redis-serverを独自に立ち上げることが重要になります。
|
||
|
||
公式のdockerfileでもdeployは成功しますが、logsを見てみると、redisの処理がうまく行かず、webにアクセスできませんでした。
|
||
|
||
さらに、独自のアドレスを使う場合は、fly.ioの`apps/xxx/certificates`で証明書を発行した上でCNAMEを追加します。ここまでやって初めて正常に動作しました。
|
||
|
||
ref : https://github.com/tmm1/flyapp-mastodon
|
||
|
||
```sh
|
||
$ fly apps create xxx
|
||
$ fly scale memory 512
|
||
```
|
||
|
||
```toml:fly.toml
|
||
app = "xxx"
|
||
|
||
kill_signal = "SIGINT"
|
||
kill_timeout = 5
|
||
|
||
[env]
|
||
# WEB_DOMAIN="mstdn.syui.ai"
|
||
# LOCAL_DOMAIN="syui.ai"
|
||
LOCAL_DOMAIN="xxx.fly.dev"
|
||
LANG="en_US.UTF-8"
|
||
RAILS_ENV = "production"
|
||
RAILS_LOG_TO_STDOUT = "enabled"
|
||
WEB_CONCURRENCY = "1"
|
||
REDIS_HOST = "xxx-redis.internal"
|
||
REDIS_PORT = "6379"
|
||
S3_ENABLED=false
|
||
SINGLE_USER_MODE=true
|
||
OTP_SECRET=""
|
||
SECRET_KEY_BASE=""
|
||
# LOCAL_HTTPS=false
|
||
|
||
[deploy]
|
||
release_command = "bundle exec rails db:migrate"
|
||
|
||
[mounts]
|
||
processes = ["rails"]
|
||
source = "mastodon_uploads"
|
||
destination = "/opt/mastodon/public/system"
|
||
|
||
[processes]
|
||
rails = "bundle exec rails s -p 8080"
|
||
sidekiq = "bundle exec sidekiq"
|
||
|
||
[[statics]]
|
||
guest_path = "/opt/mastodon/public"
|
||
url_prefix = "/"
|
||
|
||
[[services]]
|
||
internal_port = 8080
|
||
processes = ["rails"]
|
||
protocol = "tcp"
|
||
|
||
[[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"
|
||
|
||
[[services.http_checks]]
|
||
path = "/health"
|
||
grace_period = "1s"
|
||
interval = "15s"
|
||
restart_limit = 0
|
||
timeout = "2s"
|
||
```
|
||
|
||
`OTP_SECRET`, `SECRET_KEY_BASE`は`fly secrets set`したほうがいいです。ですが、secretsは不安定なので、envに書いたほうがいいです。理由は後述します。
|
||
|
||
私の場合、下記のようにDBを引き継いだのですが、反映されませんでした。
|
||
|
||
```sh
|
||
$ heroku config
|
||
$ fly pg create xxx
|
||
$ fly proxy 5432 -a xxx
|
||
---
|
||
# host=localhost
|
||
$ export DATABASE_URL=postgres://xxx:xxx@localhost:5432
|
||
$ pg_dump --no-owner -C -d $HEROKU_DATABASE_URL | psql -d $DATABASE_URL
|
||
---
|
||
$ fly pg attach -a $app $app_db
|
||
# DATABASE_URLにsecrets setしている場合はattachは動きません。unsetしてください
|
||
$ fly secrets unset DATABASE_URL
|
||
```
|
||
|
||
以前のsecret-keyなどもenvに入れて、`rails db:setup`を実行していません。引き継ぎなのでmigrateの処理を入れています。
|
||
|
||
しかし、新しくアカウントを作り直すことになったので、最初から初期化してdeployするのがおすすめかもしれません。
|
||
|
||
```sh
|
||
$ fly pg create --name xxx-pg
|
||
$ fly pg attach -a xxx xxx-pg
|
||
# fly deploy -c fly.setup.toml
|
||
```
|
||
|
||
次は、redis-serverを作ります。
|
||
|
||
```toml:fly.redis.toml
|
||
app = "xxx-redis"
|
||
|
||
[[mounts]]
|
||
source = "xxx_redis"
|
||
destination = "/data"
|
||
```
|
||
|
||
volume sizeが3G以上になる場合、課金が発生します。
|
||
|
||
```sh
|
||
$ fly apps create xxx-redis
|
||
$ fly vol create -c fly.redis.toml xxx_redis --size 1
|
||
$ fly deploy --config fly.redis.toml --build-target redis-server
|
||
```
|
||
|
||
dockerからなのか、ちょっとしたことですぐに動かなくなります。例えば、mediaのurlがうまく取得できない場合でもそういった事が起こるので、注意が必要です。問題が発生した場合、pgをresetしたほうが早いです。
|
||
|
||
```sh
|
||
$ fly vol create mastodon_uploads --size 1
|
||
```
|
||
|
||
```sh
|
||
# こういったやり方で画像をuploadしている場合は動かなくなる
|
||
PAPERCLIP_SECRET="xxx"
|
||
PAPERCLIP_ROOT_URL="https://github.com/syui/xxx/raw"
|
||
```
|
||
|
||
最終的には、appを`deploy`します。
|
||
|
||
```sh
|
||
$ fly deploy
|
||
$ fly open
|
||
```
|
||
|
||
```sh
|
||
$ fly ssh console
|
||
# https://zenn.dev/kumasun/articles/12dcc7b3e91722945228
|
||
# 新しくアカウントを作る
|
||
$ cd mastodon
|
||
$ RAILS_ENV=production bundle exec bin/tootctl accounts create $USER --email=$EMAIL --confirmed --role admin
|
||
# 既存のアカウントを上書き
|
||
$ RAILS_ENV=production bundle exec bin/tootctl accounts modify $USER --email=$EMAIL --confirm --role admin
|
||
```
|
||
|
||
sidekiqが遅い場合があり、redisが原因だと思われます。しかし、これ以上の方法があるとは思えません。
|
||
|
||
あと、fly.io(cli)は、バグっているので、まあまあの割合で有効に動作しないことがあります。なにかおかしいと思ったときは、そういうこともあるということで。私の場合、secretsに入れたはずのやつが消えたり、消したはずのやつが残ってたり、DATABASE_URLを消したあとにもattachで追加できなくなったりといったことが頻発しました。
|
||
|
||
#### mastodon/dockerfile
|
||
|
||
> 下記からは主にうまく動作しない手順となります。
|
||
|
||
通常は`fly launch`にてy/NでNにします。こうすることでdockerfileが上書きされず、mastodonのdockerfileを使用します。
|
||
|
||
```toml:fly.toml
|
||
[processes]
|
||
web = "bundle exec puma -C config/puma.rb"
|
||
worker = "bundle exec sidekiq"
|
||
|
||
[build]
|
||
[build.args]
|
||
BUNDLER_VERSION = "2.3.9"
|
||
NODE_VERSION = "14"
|
||
RUBY_VERSION = "3.0.4"
|
||
|
||
[deploy]
|
||
release_command = "bundle exec rails db:migrate"
|
||
|
||
[env]
|
||
PORT = "8080"
|
||
|
||
[[services]]
|
||
processes = ["web"] # this service only applies to the web process
|
||
http_checks = []
|
||
internal_port = 8080
|
||
protocol = "tcp"
|
||
script_checks = []
|
||
```
|
||
|
||
多少、dockerfileを手直ししてdeployすればいいです。postgres, redisのurlをenvに入れておきましょう。これはdockerfileに入れてもfly.ioに入れてもいいです。herokuからの移行は[こちら](https://fly.io/docs/rails/getting-started/migrate-from-heroku/)を参考にしてください。
|
||
|
||
```sh
|
||
$ ruby -v
|
||
$ rbenv install 3.0.4
|
||
$ bunlde
|
||
|
||
$ fly secrets set DATABASE_URL=xxx
|
||
$ fly secrets set REDIS_URL=xxx
|
||
$ fly deploy
|
||
$ fly open
|
||
```
|
||
|
||
#### fly.io/dockerfile
|
||
|
||
> 下記からは主にうまく動作しない手順となります。
|
||
|
||
fly.ioが生成するdockerfileを使ってdeployする大まかなヒントです。
|
||
|
||
> ruby '~> 3.1.0'
|
||
|
||
```sh
|
||
$ rbenv install 3.1.0
|
||
$ ruby -v
|
||
$ bundle
|
||
|
||
$ fly auth login
|
||
$ fly launch
|
||
$ fly deploy
|
||
> An error occurred while installing idn-ruby (0.1.4), and Bundler cannot
|
||
> An error occurred while installing charlock_holmes (0.7.7), and Bundler cannot
|
||
...
|
||
```
|
||
|
||
> Dockerfile
|
||
|
||
```
|
||
ARG DEV_PACKAGES="git build-essential libpq-dev wget vim curl gzip xz-utils libsqlite3-dev ffmpeg libicu[0-9][0-9] libicu-dev libidn11 libidn11-dev libpq-dev libxdamage1 libxfixes3 zlib1g-dev libcairo2 libdatrie1 libgdk-pixbuf2.0-0 libgraphite2-3 libharfbuzz0b libpango-1.0-0 libpangocairo-1.0-0 libpangoft2-1.0-0 libpixman-1-0 librsvg2-2 libthai-data libthai0 libvpx[5-9] libxcb-render0 libxcb-shm0 libxrender1 libglib2.0-0"
|
||
```
|
||
|
||
これでやっと通りました。
|
||
|
||
しかし、`bundle exec rails assets:precompile`で`libicudata.so.67: cannot open shared object file: No such file or directory - /app/vendor/bundle/ruby/3.1.0/gems/charlock_holmes`が出ます。
|
||
|
||
> Dockerfile
|
||
|
||
```sh
|
||
ENV OTP_SECRET=xxx
|
||
RUN gem pristine --all
|
||
|
||
ARG PROD_PACKAGES=xxx libglib2.0-0
|
||
```
|
||
|
||
#### postgres
|
||
|
||
fly-postgres(pg)はpublicではなくprivateです。container内からしかアクセスできません。ただし、localからアクセスする手段があります。それを使いheroku-pgのdumpをfly-pgに追加します。
|
||
|
||
```sh
|
||
$ heroku config
|
||
$ fly pg create
|
||
$ fly proxy 5432 -a xxx
|
||
---
|
||
# host=localhost
|
||
$ export DATABASE_URL=postgres://xxx:xxx@localhost:5432
|
||
$ pg_dump --no-owner -C -d $HEROKU_DATABASE_URL | psql -d $DATABASE_URL
|
||
---
|
||
$ fly pg attach --app $app $app_db
|
||
# DATABASE_URLにsecrets setしている場合はattachは動きません。unsetしてください
|
||
$ fly secrets unset DATABASE_URL
|
||
```
|
||
|
||
#### redis
|
||
|
||
fly.ioはredisがつらい。もしかしたらherokuのrediscloud使えばいいかも。でも`REDIS_URL`に入れてもうまく動作しなかった。
|
||
|
||
```sh
|
||
$ heroku addons:create rediscloud
|
||
```
|
||
|
||
総評として、herokuがよすぎた。
|
||
|
||
追記 : 調整することで、fly.ioでもかなり快適に動作するようになりました。ただし、総合的に見てherokuのほうが便利です。fly.ioはherokuより安く運用できるという点で評価できます。
|
||
|