【Error】AWS画像関係～原因が全く違った？件

# はじめに
ボタンを押した後に表示された画面。エラーが起こっていたのでエラーの発見から解決までの流れをまとめてみたいと思います

## 環境
- Windows, WSL
- Docker
- Ruby 3.2.3
- Rails 7.1.3


## どういうエラーか？
[![Image from Gyazo](https://i.gyazo.com/64af5f62351baa506441abfde57ce7fa.png)](https://gyazo.com/64af5f62351baa506441abfde57ce7fa)

- 何かしらのエラーが起こっていて、「所有者の場合はログを確認してください。」とのことなのでログを確認。

- 開発者ツールやターミナルの「docker compose up」のログにはエラー特に見当たらず。
- Renderのダッシュボードから、該当プロジェクトの「Logs」を見ると`Error`の文字を発見！
[![Image from Gyazo](https://i.gyazo.com/c1721c1cb281f131059e896ef3c7cbce.png)](https://gyazo.com/c1721c1cb281f131059e896ef3c7cbce)
- エラー文は👇
  ```
  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の設定をしました。

https://qiita.com/wa-chan222/items/5edbfa78d155bcc3171c

https://qiita.com/joinus_ibuki/items/774a79e9c828ecdc57b3


.envファイルもgignoreファイルも、uploader関係のファイルも、renderのシークレットファイルの設定もしましたが、やはり「投稿する」ボタンをおしても画像は表示されず


#### 相談
相談してみた結果、そもそも「AWSは関係ない、ImageMagickのエラーをもう一度確認」とのことで。

- `gem minimagick`という`gem`そのものは`ruby`で使用する`Imagemagick`や`graphicsmagick`を使いやすくするためのもので、サーバー上にちゃんと`Imagemagick`などがないと画像保存はできない。
- Renderでデプロイした時に`Lunguage`を`Docker`に設定したけど、これだと自分でDB変数など設定しないといけない（ちょっとここら辺の説明詳しく聞き逃してしまった💦）。つまり`dockerfile.dev`や`prod`に新しく画像関係に関する記述が必要になる。
- Renderでデプロイする時に`Ruby`言語を選択すれば勝手に画像関係の設定をしてくれる。

https://community.render.com/t/install-binary-dependencies/1130/6

👆記事のJakeさんのコメントでRubyイメージにインストールされているライブラリの現在のリストを確認できます。RenderでRubyを選択してデプロイした時にRubyが勝手に画像関係もインストールしてくれるといっっています。

#### 相談から再度デプロイ
自分で新しく記述するより再度デプロイしたほうが早いと思い、再度デプロイ実行！
[![Image from Gyazo](https://i.gyazo.com/542750d107a94770d684ea8402c28fe8.png)](https://gyazo.com/542750d107a94770d684ea8402c28fe8)

う～～ん。残念！！:sob:



<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>


## 特別相談part0
Render＞＞dashboardで該当アプリを選択＞＞Enviroment＞＞Secret Filesに.envの内容を記載しましたが「Environment Variables」に設定しなおす👇

[![Image from Gyazo](https://i.gyazo.com/95905540743dd77425bf35ad028922bf.png)](https://gyazo.com/95905540743dd77425bf35ad028922bf)

この設定の後再デプロイしたけど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ファイルの記述は正しいが、アプリケーションがこれらの変数を正しく認識していない可能性？？？

```ruby
# つぎのコードで環境変数が正しく設定されているかを確認したが表示なし！！
echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEY
```

dotenvライブラリを使用している場合、Railsのプロジェクト内で.envファイルを正しく読み込むために、config/application.rbまたは初期化ファイルに以下のコードが含まれていることを確認
```ruby
require 'dotenv'
Dotenv.load

# 上記のようなコードが必要になるそうだがなかった！！！？
# 次のコードで追記した
Dotenv::Rails.load
```

### 👆追加して再デプロイしたらとおった！！！！！ 

#### 2つのコードの違いについて
- **`Dotenv::Rails.load`** はRailsプロジェクト向けで、環境に応じた自動的な読み込みが可能。Railsアプリケーションでの利用が便利。
- **`require 'dotenv'; Dotenv.load`** は汎用的な方法で、Rails以外でも使えるが、環境ごとの制御は自分で行う必要がある。



<br>
<br>
<br>
<br>
<br>


# さいごにまとめ
- 調べて調べてうまくいかないことがある。
- 灯台もとくらし。意外とそんなことだったのか、という原因が存在する。
- リモートでの技術面談はなかなか難しいけど、利用しない手はない
- 自分から質問しに行くアクションをどんどんとれ！
- AWSの設定と画像の開発環境とローカル環境での違いを少し理解することができてよかった

<br>
<br>
<br>

# 以下内容は実行しましたが結局うまくいかず元に戻した内容。一応記憶の片隅に残しておくために記載
👇この「Exited with status1」のえらー？も何なのか探してもわからない・・・。

[![Image from Gyazo](https://i.gyazo.com/2fd0173ef877a5013d82bea45b330466.png)](https://gyazo.com/2fd0173ef877a5013d82bea45b330466)


👇一度相談part2の内容も試しましたがやはり502エラーは続いていたので元に戻しています

## 相談part2
Renderデプロイした時のログをみてみます

[![Image from Gyazo](https://i.gyazo.com/041151d1e749d814ca803b5cf9719c7f.png)](https://gyazo.com/041151d1e749d814ca803b5cf9719c7f)

上記エラーを調べて参考となりそうな記事を発見

https://qiita.com/suzy1031/items/ec6827130119874d3b54

`aws_access_key_id, aws_secret_access_key`が見当たらないそうです

- 前回設定したはずなのになぜ？
    ```
    aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
    aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
    ```
    これでいうとENVファイルからアクセスキー等を読み込むよう設定していて、こちらにはのせることはできませんが`.env`ファイルにはしっかりキーを記載しています。
<br>

- 盲点だったのが`.gitignore`でこの`.env`を読み込まないように設定していたこと
   ```
   # Ignore all environment files (except templates).
   /.env*
   !/.env*.erb
   ```
   この設定により本番環境でエラーが生じていた？！


### 記事を参考に設定しなおす
```ruby
# 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」を押すといつものターミナルに戻ってこれます
```

```ruby
#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の設定を変更してみる

https://qiita.com/mattan5271/items/96721426cff2b1d67cdd

```
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
```