はじめに
ボタンを押した後に表示された画面。エラーが起こっていたのでエラーの発見から解決までの流れをまとめてみたいと思います
環境
- Windows, WSL
- Docker
- Ruby 3.2.3
- Rails 7.1.3
どういうエラーか?
-
何かしらのエラーが起こっていて、「所有者の場合はログを確認してください。」とのことなのでログを確認。
-
開発者ツールやターミナルの「docker compose up」のログにはエラー特に見当たらず。
-
エラー文は👇
E, [2024-09-29T08:29:25.340159 #11] ERROR -- : [a336f55b-cf12-41ca-984e-1140d793980e] [a336f55b-cf12-41ca-984e-1140d793980e] MiniMagick::Error (You must have ImageMagick or GraphicsMagick installed):
-
MiniMagick::Errorというエラーが発生。アプリケーションが画像を処理するために「ImageMagick」または「GraphicsMagick」というソフトウェアを必要としているのに、それらがインストールされていないといっています。(ローカルではインストールしたはずなのに??)
解決方法
ImageMagickまたはGraphicsMagickをインストールする
Ubuntu(Linux)を使用しているので以下手順で進めていきます。
1:インストールされているか確認
そもそもインストールされているか確認していきます
# ImageMagickがインストールされているか確認。次のどちらかで確認
magick -version
convert -version
# GraphicsMagickがインストールされているか確認
gm -version
2:インストールされていた
1を行ったら次のようなログが表示されました。
ImageMagick 6.9.11-60がインストールされていることが確認でき、ImageMagick自体はインストールされていることがわかりました
# convert -version
Version: ImageMagick 6.9.11-60 Q16 x86_64 2021-01-25 https://imagemagick.org
Copyright: (C) 1999-2021 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC Modules OpenMP(4.5)
Delegates (built-in): bzlib djvu fftw fontconfig freetype heic jbig jng jp2 jpeg lcms lqr ltdl lzma openexr pangocairo png tiff webp wmf x xml zlib
しかしエラーが出ているという事は、アプリケーション側がImageMagickを正しく認識できていない可能性があるという事。
3:MiniMagickがImageMagickを使えるか確認
RubyアプリケーションでMiniMagick
がImageMagick
にアクセスできない場合があるため、以下のコマンドを使ってMiniMagickが動作しているか確認します
bundle exec rails console
MiniMagick::Tool::Convert.version
# 返ってきたログ
Loading development environment (Rails 7.1.3.4)
irb(main):001> MiniMagick::Tool::Convert.version
irb(main):002>
(irb):1:in <main>': undefined method version' for MiniMagick::Tool::Convert:Class (NoMethodError)
MiniMagick::Tool::Convert.version
つまり、ImageMagick
が正しくインストールされていても、MiniMagick
の使い方が間違っている可能性があるという事がわかりました。が投稿するボタン押してもエラーは続く。
さらに模索~相談~相談の解決策を試す
本番環境で画像が表示されていないからそちらが原因なのかと思いAWSの設定をしました。
.envファイルもgignoreファイルも、uploader関係のファイルも、renderのシークレットファイルの設定もしましたが、やはり「投稿する」ボタンをおしても画像は表示されず
相談
相談してみた結果、そもそも「AWSは関係ない、ImageMagickのエラーをもう一度確認」とのことで。
-
gem minimagick
というgem
そのものはruby
で使用するImagemagick
やgraphicsmagick
を使いやすくするためのもので、サーバー上にちゃんとImagemagick
などがないと画像保存はできない。 - Renderでデプロイした時に
Lunguage
をDocker
に設定したけど、これだと自分でDB変数など設定しないといけない(ちょっとここら辺の説明詳しく聞き逃してしまった💦)。つまりdockerfile.dev
やprod
に新しく画像関係に関する記述が必要になる。 - Renderでデプロイする時に
Ruby
言語を選択すれば勝手に画像関係の設定をしてくれる。
👆記事のJakeさんのコメントでRubyイメージにインストールされているライブラリの現在のリストを確認できます。RenderでRubyを選択してデプロイした時にRubyが勝手に画像関係もインストールしてくれるといっっています。
相談から再度デプロイ
自分で新しく記述するより再度デプロイしたほうが早いと思い、再度デプロイ実行!
う~~ん。残念!!
特別相談part0
Render>>dashboardで該当アプリを選択>>Enviroment>>Secret Filesに.envの内容を記載しましたが「Environment Variables」に設定しなおす👇
この設定の後再デプロイしたけど502エラーはまだまだ続く
エラー内容に少し変化?
I, [2024-10-06T10:55:50.918802 #114] INFO -- : [dotenv] Loaded .env
[114] ! Unable to load application: ArgumentError: Missing required arguments: aws_access_key_id, aws_secret_access_key
bundler: failed to load command: puma (/opt/render/project/.gems/bin/puma)
/opt/render/project/.gems/ruby/3.2.0/gems/fog-core-2.5.0/lib/fog/core/service.rb:244:in validate_options': Missing required arguments: aws_access_key_id, aws_secret_access_key (ArgumentError)
このエラーメッセージは、Ruby on RailsアプリケーションがAWSに関連する設定情報(aws_access_key_idやaws_secret_access_key)が不足しているため、アプリケーションのロードに失敗していることを示しています。
具体的には、fog-coreというライブラリがAWSにアクセスするために必要な認証情報が不足していることが原因です。pumaというアプリケーションサーバーが起動しようとしている際に、dotenvが.envファイルをロードしていますが、そのファイルに正しいAWSのアクセスキーIDとシークレットキーが含まれていない、または誤って設定されている可能性があります。
「.env」ファイルは適切に設定されている。他の原因…。
.envファイルの記述は正しいが、アプリケーションがこれらの変数を正しく認識していない可能性???
# つぎのコードで環境変数が正しく設定されているかを確認したが表示なし!!
echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEY
dotenvライブラリを使用している場合、Railsのプロジェクト内で.envファイルを正しく読み込むために、config/application.rbまたは初期化ファイルに以下のコードが含まれていることを確認
require 'dotenv'
Dotenv.load
# 上記のようなコードが必要になるそうだがなかった!!!?
# 次のコードで追記した
Dotenv::Rails.load
👆追加して再デプロイしたらとおった!!!!!
2つのコードの違いについて
-
Dotenv::Rails.load
はRailsプロジェクト向けで、環境に応じた自動的な読み込みが可能。Railsアプリケーションでの利用が便利。 -
require 'dotenv'; Dotenv.load
は汎用的な方法で、Rails以外でも使えるが、環境ごとの制御は自分で行う必要がある。
さいごにまとめ
- 調べて調べてうまくいかないことがある。
- 灯台もとくらし。意外とそんなことだったのか、という原因が存在する。
- リモートでの技術面談はなかなか難しいけど、利用しない手はない
- 自分から質問しに行くアクションをどんどんとれ!
- AWSの設定と画像の開発環境とローカル環境での違いを少し理解することができてよかった
以下内容は実行しましたが結局うまくいかず元に戻した内容。一応記憶の片隅に残しておくために記載
👇この「Exited with status1」のえらー?も何なのか探してもわからない・・・。
👇一度相談part2の内容も試しましたがやはり502エラーは続いていたので元に戻しています
相談part2
Renderデプロイした時のログをみてみます
上記エラーを調べて参考となりそうな記事を発見
aws_access_key_id, aws_secret_access_key
が見当たらないそうです
- 前回設定したはずなのになぜ?
これでいうとENVファイルからアクセスキー等を読み込むよう設定していて、こちらにはのせることはできませんが
aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'], aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
.env
ファイルにはしっかりキーを記載しています。
- 盲点だったのが
.gitignore
でこの.env
を読み込まないように設定していたことこの設定により本番環境でエラーが生じていた?!# Ignore all environment files (except templates). /.env* !/.env*.erb
記事を参考に設定しなおす
# credentials.yml.encを編集する
docker compose exec web bash
$ EDITOR=vim bin/rails credentials:edit
# すると色々表示される中awsに関する記述があり、デフォルトでコメントアウトされているので外し、取得したidとkeyをこちらに入力
#ターミナル右下に「All」が表示されているときは「ノーマルモード」です
#挿入モードにするため「i」をおすと「INSERT」が表示
aws:
access_key_id: 123
secret_access_key: 345
#編集が完了したら「esc」を押して編集モードからノーマルモードに戻る
#保存して終了なら「:wq」、保存しないで終了なら「:q!」。で「Enter」を押すといつものターミナルに戻ってこれます
#config/initializers/carrierwave.rbの編集
aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
#この設定をcredentials下にaws_access_key_idとaws_secret_access_keyはあるよという内容に変更する
aws_access_key_id: Rails.application.credentials.aws[:access_key_id],
aws_secret_access_key: Rails.application.credentials.aws[:secret_access_key],
やはりうまくいかず
相談2で変更した内容を一度元に戻し再度AWSの設定を変更してみる
require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'
CarrierWave.configure do |config|
config.storage :fog
config.fog_provider = 'fog/aws'
config.fog_directory = 'train2bucket'
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: Rails.application.credentials.aws[:access_key_id],
aws_secret_access_key: Rails.application.credentials.aws[:secret_access_key],
region: 'ap-northeast-1', # リージョン
path_style: true
}
end
require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'
CarrierWave.configure do |config|
if Rails.env.production? # 本番環境の場合はS3へアップロード
config.storage :fog
config.fog_provider = 'fog/aws'
config.fog_directory = 'train2bucket' # バケット名
config.fog_public = false
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: ENV['S3_ACCESS_KEY_ID'], # アクセスキー
aws_secret_access_key: ENV['S3_SECRET_ACCESS_KEY'], # シークレットアクセスキー
region: 'ap-northeast-1', # リージョン
path_style: true
}
else # 本番環境以外の場合はアプリケーション内にアップロード
config.storage :file
config.enable_processing = false if Rails.env.test?
end
end
# Ignore all environment files (except templates).
/.env*
!/.env*.erb
これを削除(コメントアウト)して次を追加?
/.env