こんにちは。
早く駆け出しエンジニアになりたい@iloveomeletteです。
標題にある通り、Capistranoを使ってデプロイした際に少々苦戦したので、
共有していこうと思います。
ポケモンのジム戦のようにエラーを解決するたび、またエラーに遭遇するということを繰り返してました。しょうもないエラーも紹介しつつ解決までの過程を書いていきます。
誰かの参考になれば幸いです。
尚、ご指摘箇所がございましたら
ご教授いただけますと幸いです。
それでは以下の目次でお送り致します。
| ラウンド | エラー項目 |
|---|---|
| 1 | VS 『supports platforms』 問題 |
| 2 | VS 『An error occurred while installing mysql2 (0.5.3)』 問題 |
| 3 | VS 『Mysql2::Error: Unknown database 'アプリ名_production'』 問題 |
前提
それでは、まず環境などの前提部分からですね。
- macOS Monterey 12.3.1 (M1)
- Ruby 3.1.1
- Rails 6.1.5
- nginx
- puma
- MariaDB 10.6.7
利用しているAWSサービスはEC2とRDSを利用していて「Amazon Linux 2 AMI」の「t2.micro」を選択しています。こんなところでしょうか。追加があれば追加していきます。
* サーバー環境のターミナル => EC2にログインした状態
* ローカル環境のターミナル => 通常のターミナル
以降の話はこちらのコマンド実行後の話です。
$ bundle exec cap production deploy BRANCH=HEAD
ラウンド1 『supports platforms』 問題
それでは初戦ですね。
結論
先に結論を述べると以下のコマンドを実行してこの問題を倒すことができました。
$ bundle lock --add-platform x86_64-linux
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Writing lockfile to ~~~/アプリ名/Gemfile.lock
エラー箇所と謎解き
途中までは上手くいっていたのですが、以下のエラーが発生しました(以降、省略するときは「###」を挟みます)
###
00:35 bundler:install
01 Your bundle only supports platforms ["x86_64-darwin-21"] but your local platform
01 is x86_64-linux. Add the current platform to the lockfile with
01 `bundle lock --add-platform x86_64-linux` and try again.
###
status: 16 (SSHKit::Runner::ExecuteError)
bundle stdout: Nothing written
bundle stderr: Your bundle only supports platforms ["x86_64-darwin-21"] but your local platform
is x86_64-linux. Add the current platform to the lockfile with
`bundle lock --add-platform x86_64-linux` and try again.
###
** DEPLOY FAILED
** Refer to log/capistrano.log for details. Here are the last 20 lines:
###
DEBUG [5d094cc5] Your bundle only supports platforms ["x86_64-darwin-21"] but your local platform
is x86_64-linux. Add the current platform to the lockfile with
`bundle lock --add-platform x86_64-linux` and try again.
これはつまり「お使いのbundleは"x86_64-darwin-21"のみサポートしてるけど、あなたのローカル環境は"x86_64-linux"だからこれを追加してね」ということですね。
親切なことにbundle lock --add-platform x86_64-linuxをしてねと教えてくれています。
では、このbundle lockとは何なのでしょうか。
公式リファレンスによるとbundle lockは
Creates / Updates a lockfile without installing
であると、つまり「インストールなしでlockfileを生成したり更新したりする」コマンドですね。
では--add-platformは何をするのでしょうか。察しがつくと思いますが、
Add a new platform to the lockfile, re-resolving for the addition of that platform.
であると、つまり「lockfileに新しいプラットフォームを追加して再解決する」コマンドですね。
このコマンドを実行後、再度コミット、プッシュしてデプロイを実行するとこの問題を倒すことができました。
ラウンド2 『An error occurred while installing mysql2 (0.5.3)』 問題
先ほどのエラーを倒してやっとデプロイができると思っていた矢先、すぐにバトルが始まります。
結論
結論から述べると以下のコマンドを実行してMariaDB関連のインストールを行えば解決します。
$ sudo yum install -y MariaDB-devel MariaDB-shared
ここはかなりご自身の環境によって大きく問題が異なる可能性が高いのでエラー文をよく読むことをお勧めします。
エラー箇所と謎解き
エラー内容は以下の通り
00:31 bundler:install
01 Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
###
01 Could not create Makefile due to some reason, probably lack of necessary
01 libraries and/or headers. Check the mkmf.log file for more details. You may
01 need configuration options.
###
01 /home/****/.rbenv/versions/3.1.1/lib/ruby/3.1.0/mkmf.rb:1086:in `block
01 in find_library': undefined method `split' for nil:NilClass (NoMethodError)
01
01 paths = paths.flat_map {|path| path.split(File::PATH_SEPARATOR)}
01 ^^^^^^
01 from
###
Caused by:
SSHKit::Command::Failed: bundle exit status: 5
bundle stdout: Nothing written
bundle stderr: Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
###
** DEPLOY FAILED
** Refer to log/capistrano.log for details. Here are the last 20 lines:
###
An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue.
In Gemfile:
mysql2
エラー文を読んでみると「mysql2 (0.5.3)をインストールしている間にエラーが発生して続けることができませんでした」というような内容ですね。
そもそもmysql2とは何なのでしょうか。
mysql2のREADMEによると
Mysql2 - A modern, simple and very fast MySQL library for Ruby - binding to libmysql
「Ruby用のモダンでシンプルかつ非常に高速なMySQLのライブラリである」と言っています。
つまり、RailsでMySQLを利用するために必要なものであると言えます。
少し話が逸れましたが、4行目付近でこのようなことを言っています。
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details.
You may need configuration options.
つまり、「詳細を知りたいならmkmf.logをチェックしなさい」と言っていますので、このログを見てみましょう。
途中でこのようなメッセージがあると思うので、そのパスを使用します。
To see why this extension failed to compile, please check the mkmf.log which can
be found here:
# 下記のパスを使用します
~~~/shared/bundle/ruby/3.1.0/extensions/x86_64-linux/3.1.0/mysql2-0.5.3/mkmf.log
catコマンドを利用してログの中身を見てみましょう、と言いたいところなのですが勉強不足のため、このログを見てもいまいちピンと来ませんでした。念の為、見てみることをお勧めします。
$ cat ~~~/shared/bundle/ruby/3.1.0/extensions/x86_64-linux/3.1.0/mysql2-0.5.3/mkmf.log
では、どうしたかというと先ほどのメッセージの1文前のメッセージを見てみると
Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers.
これは「Makefileをいろんな理由により作れなかったよ。多分、必要なライブラリやヘッダーが足りないからかも」と言っています。エラー文で様々調査を行なっているとあるGitHub Issuesに辿り着きます。ここではyum install -y Mariadb-devel Mariadb-sharedをTryしてみてと言っています。他の記事でもこのコマンドを見かけていたので、そもそもこの2つは何なんだと調べてみました。
公式MariaDB(少しバージョンは古いですが)によると
MariaDB-devel - Development headers and static libraries.
MariaDB-shared - Dynamic client libraries.
な、なんかこれっぽい...
そうです。MariaDBをインストールする際は、公式AWSを参考にして導入していたので、Rails用に必要なものをインストールできていなかったということですね。
後付けではありますが、mysql2のREADMEでも以下のように記されています。
You may need to install a package such as libmariadb-dev, libmysqlclient-dev, mysql-devel, or other appropriate package for your system.
RailsからMariaDBを操作するので、少なくともMariadb-develは必要みたいです。
ということで、MariaDB関連のインストールを行なって、このエラーを倒すことができました。
$ sudo yum install -y MariaDB-devel MariaDB-shared
# 以下を実行してRDSのMariaDBにログイン
$ mysql -h エンドポイント -u root -p
# 以下を実行してデータベースを確認
MariaDB [(none)]> show databases;
# 表示されたデータベース一覧に「アプリ名_production」があるか確認
ラウンド3 『Mysql2::Error: Unknown database 'アプリ名_production'』 問題
さあ、これでやっとデプロイできるかなと思った矢先、またまたエラーと遭遇します。
ここはサクッと終わらせます。
結論
とてもつまらないミスでした。
production:
<<: *default
- database: AB_app_production
+ database: A_B_app_production
username: -
password: <%= Rails.application.credentials.db[:password] %>
host: <%= Rails.application.credentials.db[:hostname] %>
エラー箇所と謎解き
では、どのようなエラーか見ていきます。
01:52 deploy:migrating
01 $HOME/.rbenv/bin/rbenv exec bundle exec rake db:migrate
01 rake aborted!
01 ActiveRecord::NoDatabaseError: Unknown database 'AB_app_production'
###
Caused by:
Mysql2::Error: Unknown database 'AB_app_production'
今度は「よく分からんデータベースがあるよ」と言われています。
この時、疲れていた私はMariaDBの再起動などを試したりしていました。
ここで言いたいことはちゃんとエラー文をよく見ろということですね。
例えば、私のアプリは「A_B_app_production」なのですが、ここで示されているものは
「AB_app_production」ということですね。これを見分けるのは難しいですね笑
まずはタイポがあるか確認することが大事だと痛感しました。
余談ですが、恐らく最初のアプリ立ち上げで命名する際に「 _(アンダースコア) 」を入れ忘れたんですね。
では、以下のように修正してコミット、プッシュ後に再度デプロイをします。
production:
<<: *default
- database: AB_app_production
+ database: A_B_app_production
username: -
password: <%= Rails.application.credentials.db[:password] %>
host: <%= Rails.application.credentials.db[:hostname] %>
これにてやっとデプロイに成功しました!!
で、す、が! 本当の地獄はここからでした。
次回は、実際にElastic IPにアクセスしてアプリが表示されるか確認をした際の奮闘記をお届けします。