Rails APIをfly.ioにデプロイする中で詰まったこと
はじめに
私は個人開発でRails APIをHerokuにデプロイしていました。Herokuの無料枠が外れるとのことで、新しく無料でRails APIをデプロイすることが出来るFly.ioを試してみました。
環境
windows
ruby 3.0.3
rails 7.0.3
前提
Rails APIをローカルで動かすことが出来る。
実際にやってみる
まずは、flyのコマンドをターミナルで使えるようにするために、flyctlをインストールします。
iwr https://fly.io/install.ps1 -useb | iex
flyの認証
flyにデプロイするプロジェクトの直下に行き、以下のコマンドで認証します
flyctl auth signup
flyctl auth login
flyctl launch
次にプロジェクトの直下で以下のコマンドを打ちます
windowsではflyではなく、flyctlコマンドを使うので注意して下さい
flyctl launch
以下のように聞かれますので、プロジェクト名を入力します
ここではrails-api-testというプロジェクトです
? App Name (leave blank to use an auto-generated name):rails-api-test
次にリージョンを選択します。
Tokyo Japanのままエンター
Postgresqlの設定をするならyでエンターを押します
私はPostgresqlを使用するのでyを押しました
お金をかけたくないならば、一番上を選択
launchが完了します
flyctl deploy
その1 改行コード問題
ここで私はflyctl deploy
コマンドを実行しましたが、次のエラーが出てしまいました
flyctl deploy
Update available 0.0.418 -> v0.0.429.
Run "flyctl.exe version update" to upgrade.
==> Verifying app config
--> Verified app config
==> Building image
Remote builder fly-builder-aged-hill-8650 ready
==> Creating build context
--> Creating build context done
==> Building image with Docker
--> docker host: 20.10.12 linux x86_64
[+] Building 0.0s (0/1)
[+] Building 3.5s (20/20) FINISHED
=> [internal] load remote build context
~~~~~~~~~ 省略 ~~~~~~~~~~
=> CACHED [stage-3 5/7] COPY . . 0.0s
=> CACHED [stage-3 6/7] RUN chmod +x /app/bin/* && sed -i 's/ruby. 0.0s
=> ERROR [stage-3 7/7] RUN bin/rails fly:build 0.4s
------
> [stage-3 7/7] RUN bin/rails fly:build:
#20 0.377 /usr/bin/env: ‘ruby\r’: No such file or directory
------
Error failed to fetch an image or build from source: error building: executor failed running [/bin/bash -o pipefail -c ${BUILD_COMMAND}]: exit code: 127
このエラーはwindowsの改行コードがCRLFで発生するエラーなので、改行コードをLFに直します。
ここでは、bin/railsでエラーが出ているので、bin/railsファイルに行き、vscodeの下にあるCRLFをクリックし、LFに直して保存します。
CRLFをクリック
LFをクリック
bin/railsファイルの改行コードをがLFに直ったことを確認し、保存する
参考
その2 assets:precompile問題
改行コードを直したので、再度flyctl deploy
を実行したのですが、また新しいエラーが出てしまいました
flyctl deploy
Update available 0.0.418 -> v0.0.429.\ruby\rails\tests\test-api>
Run "flyctl.exe version update" to upgrade.
==> Verifying app config
--> Verified app config
==> Building image
~~~~~~~~~~~ 省略 ~~~~~~~~~~~~
=> CACHED [stage-3 6/7] RUN chmod +x /app/bin/* && sed -i 's/ruby. 0.0s
=> ERROR [stage-3 7/7] RUN bin/rails fly:build 3.3s
------
> [stage-3 7/7] RUN bin/rails fly:build:
#20 3.247 rails aborted!
#20 3.247 Don't know how to build task 'assets:precompile' (See the list of available tasks with `rails --tasks`)
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task_manager.rb:59:in `[]'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task.rb:66:in `lookup_prerequisite'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task.rb:62:in `block in prerequisite_tasks'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task.rb:62:in `map'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task.rb:62:in `prerequisite_tasks'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task.rb:241:in `invoke_prerequisites'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task.rb:218:in `block in invoke_with_call_chain'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `synchronize'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task.rb:199:in `invoke_with_call_chain'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/task.rb:188:in `invoke'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/application.rb:160:in `invoke_task'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block (2 levels) in top_level'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `each'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/application.rb:116:in `block in top_level'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/application.rb:125:in `run_with_threads'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/application.rb:110:in `top_level'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/railties-7.0.3.1/lib/rails/commands/rake/rake_command.rb:24:in `block (2 levels) in perform'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/application.rb:186:in `standard_exception_handling'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/railties-7.0.3.1/lib/rails/commands/rake/rake_command.rb:24:in `block in perform'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/rake-13.0.6/lib/rake/rake_module.rb:59:in `with_application'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/railties-7.0.3.1/lib/rails/commands/rake/rake_command.rb:18:in `perform'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.13.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
#20 3.247 /app/vendor/bundle/ruby/3.0.0/gems/bootsnap-1.13.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
#20 3.247 Tasks: TOP => fly:build#20 3.247 (See full trace by running task with --trace)
------Error failed to fetch an image or build from source: error building: executor failed running [/bin/bash -o pipefail -c ${BUILD_COMMAND}]: exit code: 1
これは、flyのbuildにassets:precompileを使用しようとしているのですが、Rails APIではassetsが無いためエラーが出てしまいます。
そこで私は、assets:precompileの箇所をそれ以外のコードに書き換えました。
恐らく、何でも良いと思いますが、ここではdb:createに変えています。
- task :build => 'assets:precompile'
+ task :build => 'db:create'
その3 database問題
再度、flyctl deploy
をしますが、また新たにエラーが出てしまいました
=> [stage-3 5/7] COPY . . 0.0s
=> [stage-3 6/7] RUN chmod +x /app/bin/* && sed -i 's/ruby.exe/rub 0.3s
=> ERROR [stage-3 7/7] RUN bin/rails fly:build 3.0s
------
flyctl deploy
~~~~~~~~~ 省略 ~~~~~~~~~~~
> [stage-3 7/7] RUN bin/rails fly:build:
#20 2.946 We could not find your database: postgres. Which can be found in the database configuration file located at config/database.yml.
#20 2.946
#20 2.946 To resolve this issue:
#20 2.946
#20 2.946 - Did you create the database for this app, or delete it? You may need to create your database.
#20 2.946 - Has the database name changed? Check your database.yml config has the correct database name.
#20 2.946
#20 2.946 To create your database, run:
#20 2.946
#20 2.946 bin/rails db:create
#20 2.946 Couldn't create '' database. Please check your configuration.
#20 2.946 rails aborted!
#20 2.946 ActiveRecord::NoDatabaseError: We could not find your database: postgres. Which can be found in the database configuration file located at config/database.yml.
#20 2.946
#20 2.946 To resolve this issue:
#20 2.946
#20 2.946 - Did you create the database for this app, or delete it? You may need to create your database.
#20 2.946 - Has the database name changed? Check your database.yml config has the correct database name.
#20 2.946
#20 2.946 To create your database, run:
#20 2.946
#20 2.946 bin/rails db:create
~~~~~~~~~ 省略 ~~~~~~~~~
以前、このプロジェクトはHerokuにデプロイしており、database.ymlと、Gemfileをpostgresqlの設定に変更していたので、初期状態に戻します
default: &default
adapter: sqlite3
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000
development:
<<: *default
database: db/development.sqlite3
test:
<<: *default
database: db/test.sqlite3
- production:
- <<: *default
- adapter: postgresql
- encoding: unicode
- pool: 5
+ production:
+ <<: *default
+ database: db/production.sqlite3
- group :development, :test do
- gem 'sqlite3'
- end
- group :production do
- gem 'pg'
- end
+ gem "sqlite3"
+ gem "pg"
ですが、またエラーが出てしまいました。
その4 よくわからない問題
このエラーが全然分からなく、新しく一からRails api を作成して、この方法でデプロイすることが出来たのですが、なぜか既存のアプリは失敗してしまいました。
そこで、試しにGitHubからプロジェクトをgit clone
して同じ状態にしてみました
git clone 自分のリポジトリ
cd 自分のリポジトリ
code .
問題である、その1~3を直した後で、
bundle install
rails db:create
rails db:migrate
これで、再度flyctl deploy
を実行すると、ついにデプロイすることが出来ました
-- change_column(:users, :email, :string, {:null=>false, :unique=>true})
-> 0.0017s
== 20220810054326 AddPasswordToUsers: migrated (0.0171s) ======================
Starting clean up.
Running release task (running)... 🌍 ==> Monitoring deployment
Running release task (running)... 🌍
1 desired, 1 placed, 0 healthy, 0 unheal
1 desired, 1 placed, 0 healthy, 0 unheal
1 desired, 1 placed, 0 healthy, 0 unheal
1 desired, 1 placed, 1 healthy, 0 unheal
1 desired, 1 placed, 1 healthy, 0 unhealthy [health checks: 1 total, 1 passing]
--> v0 deployed successfully
デプロイされたサイトの確認
以下のページに行き、実際にデプロイされたかを確認します
画面下に行くと、デプロイされたプロジェクトがあるのでクリックします。ここではrails-api-test
Hostnameにある所を押せば、デプロイされたURLにアクセス出来ます
おまけ GitHub Actionsでfly.ioのCD
GitHubのmasterブランチにマージされた時に、自動でfly.ioにデプロイ出来るように設定します。
ここで紹介されている、.github/workflows/fly.yml
ファイルをそのまま使うと、私は上手く出来なかったので以下のように修正しました。
on:
push:
branches:
- master
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
jobs:
deploy:
name: Deploy app
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: superfly/flyctl-actions/setup-flyctl@master
- run: flyctl deploy --remote-only
終わり
今回はfly.ioにRails APIをデプロイする上で、詰まったことについてまとめました。
私自身、Railsの経験が薄いので、おかしいことをしているかもしれませんが、ご了承ください
かなり、デプロイするのに苦労しましたが、この記事をみてRails APIのデプロイに成功する人がいれば嬉しいです。
ここまででデプロイが出来なかった方は、こちらの方法を試してみると良いと思います
最後まで読んで下さり、ありがとうございました。
Discussion