Rails7.0.4.2・Active Storage・Docker環境でrender.comにデプロイ、ストレージはS3に保存 → JavaScriptが動かない

## この記事を書いた背景・概要
　「Rails7.0.4.2」「Active Storage」「Docker」の環境で、「render.com」にデプロイし「ストレージをS3に保存」するのに、そしてS3に保存ができるようになった後は、JavaScriptが動かなくなる苦労をしました。そこで今回、同じにように困っている方への参考になるのではと思い、記事を書きました。
　「Ruby on Rails チュートリアル-第7版-13.4マイクロポストの画像投稿（[参考1](#参考)）」を元に、ローカル環境から「render.com」にデプロイし、「ストレージはS3に保存」をすることは自体はできていましたが、「Docker」を使用した場合では設定の仕方が違った為、その方法をこちらに記述致します。
　「render.com」ではフリープランを使用していると、インスタンスは永続ディスクによってバックアップされず。インスタンスが再起動するたびに、そのデータはすべて失われるので、それを防ぐ為に「S3」を導入しています。

> 【英文】
> Ephemeral storage
> Free Redis instances are not backed by a persistent disk. Whenever an instance restarts, all of its data is lost.
> 
> 【訳文】
> エフェメラル・ストレージ
> フリーのRedisインスタンスは永続ディスクによってバックアップされていません。インスタンスが再起動するたびに、そのデータはすべて失われます。
> （[参考2](#参考)）

## 開発環境
ruby 3.1.4
Rails 7.0.4.2
psql (PostgreSQL) 15.1
Docker 23.0.5
docker-compose 3
macOS Monterey 12.6

## 目次
- [前提](#前提)
- [今回記述したDockerFile](#今回記述したdockerfile)
- [今回記述したentrypoint.sh](#今回記述したentrypointsh)
- [`config/credentials.yml.enc`の編集](#configcredentialsymlencの編集)
- [「render.com」で環境変数の設定](#rendercomで環境変数の設定)
- [別途render.comへのデプロイに関して](#別途rendercomへのデプロイに関して)
- [JavaScriptが動かない時に`config.assets.compile = true`はやってはいけない](#javascriptが動かない時にconfigassetscompile--trueはやってはいけない)
- [参考](#参考)

## 前提
　ローカル環境からは「render.com」にデプロイし、ストレージは「S3」に保存することは可能な方向けの内容となります。
　この具体的なやり方は、「Ruby on Rails チュートリアル-第7版-13.4マイクロポストの画像投稿（[参考1](#参考)）」に、記述されているので参考にする事ができます。
- Active Storageの導入
- `gem "aws-sdk-s3`の導入
- AWS（S3）の設定方法
- ローカル環境から「render.com」にデプロイしたアプリに対し、「ストレージはS3に保存」を設定する

以上が記載されています。「render.com」自体へのデプロイは、「Ruby on Rails チュートリアル-第7版-13章」以前の章にも詳しく載っているので、参考にしてください。

## 今回記述したDockerFile
```dockerfile
FROM ruby:3.1

RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock

RUN gem update --system
RUN bundle update --bundler

RUN bundle install
COPY . /myapp

## Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

## Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
```

## 今回記述したentrypoint.sh
```sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

bundle exec rails assets:precompile RAILS_ENV=production
bundle exec rails assets:clean RAILS_ENV=production
bundle exec rails db:migrate RAILS_ENV=production
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```
※開発環境でdockerが動かなくなってしまったら、こちらをご参考にしていただけると動くかもしれません。（私は動くようになりました）
[Rails開発環境でBootstrapが効かなくなってしまった時にしたこと](https://qiita.com/delicha/items/2a1a5e414953fc6e82b3)

## `config/credentials.yml.enc`の編集
　下記の様にDockerコンテナ内で、`EDITOR=vim bin/rails credentials:edit`として、`config/credentials.yml.enc`を開きます。
　Dockerコンテナ内でvimが起動しない場合は、([参考3・4](#参考))を参照してください。
 
```terminal
$ docker compose exec web bash
/myapp# EDITOR=vim bin/rails credentials:edit
```

　下記の様に、それぞれ記述をしてください。「#」がデフォルトで記述されていますが、こちらを付けっぱなしにしておくと、「コメントアウト」と同意なので消してください。また、こちらはymlファイルの為、インデントに要注意です。([参考5](#参考))

```yaml
aws:
  access_key_id: アクセスキー
  secret_access_key: シークレットアクセスキー
  s3:
    region: リージョン
    bucket: バケット名
```



## `config/storage.yml`の編集

　下記の様に記述をしてください([参考5](#参考))。こちらもymlファイルの為、インデントに要注意です。

```yml
.
.
.
amazon:
  service: S3
  access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
  secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
  region: <%= Rails.application.credentials.dig(:aws, :s3, :region) %>
  bucket: <%= Rails.application.credentials.dig(:aws, :s3, :bucket) %>
```

## 「render.com」で環境変数の設定
![スクリーンショット 2023-11-16 1.41.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1727670/9c22892b-46ed-45a1-5248-4a227af12ced.png)


　Railsチュートリアルの設定と違い、ここで必要な設定箇所が２点あります。
#### 1. keyを`RAILS_ENV`にして、valueを`production`にする
　上のスクショでは伏せ字になっていますが、`RAILS_ENV`に対しては、`production`を記述しています。こちらを記述し、本番環境の設定が記述されている`config/environments/production.rb`を読み込むようにします。この記述をしないと`config/environments/development.rb`を読み込み、開発環境の設定で実行されてしまっているようで、S3に画像データが保存されませんでした。（[参考6・7](#参考)）
　　「[参考7](#参考)」はherokuに関する記事ですが、Docker経由だと特に指定をしなければdevelopment環境で動作しているらしいです、ローカルから本番環境（今回は「render.com」ですが）にデプロイを行うとデフォルトでproductionとして扱われますが、Dockerの場合は`RAILS_ENV`に`production`をセットする必要があるようです。

> 実はRAILS_ENVが空になっていてdevelopment環境で動作していたりします。普通にRailsアプリをherokuへプッシュすると自動的に環境変数を設定してくれているので意識することは無いので見落としていたりします。RAILS_ENV=productionで環境変数をセットしましょう。([参考7](#参考))

#### 2. keyを`RAILS_SERVE_STATIC_FILES`にして、valueを`enabled`にする
　今回は静的ファイルを配信したいので、`RAILS_SERVE_STATIC_FILES`に`enabled`を記述します。上のスクショでは伏せ字になっていますが、`RAILS_SERVE_STATIC_FILES`に対しては、`enabled`を記述しています。`enabled`とすることにより、`true`の扱いになります。この様にしないと、今回はJavaScriptが動きませんでした。
>public/ディレクトリ内の静的アセットを配信するかどうかを指定します。デフォルトではtrueが設定されますが、production環境ではアプリケーションを実行するNginxやApacheなどのサーバーが静的アセットを扱う必要があるので、falseに設定されます。([参考8](#参考))

## 別途render.comへのデプロイに関して
- render.comにAWS関連の環境変数設定は不要
　AWS関連の設定は今回、`config/credentials.yml.enc`で行なっているので、render.comの環境変数設定画面では入力をする必要がありません。（render.comにAWSの環境変数をセットする方法で上手く行くかは、実験をしていません。） <br><br>
- デプロイが上手くいかない時は`Clear build cache & deploy`も試す
　今までの設定を行った上で、render.comへのデプロイが上手くいかない場合は、`Clear build cache & deploy`でのデプロイも試してみてください。
 ![20E05A90-A35B-4BA7-A8FD-F5AAF5D7183C.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1727670/e7b11738-7656-ada5-cc30-8c5195016e76.jpeg)

## JavaScriptが動かない時に`config.assets.compile = true`はやってはいけない
　JavaScriptが動かない時に調べていると出てくる、`config.assets.compile = true`という情報が出てきますが、この方法はやってはいけないとのこと。私も、最初はこの方法でやっていました😭
>config/environments/production.rb の config.assets.compile = false の値を true に変更すれば解決します。この方法はめちゃくちゃ手っ取り早いです。いちいち自分が書いたコードを調べて修正しなくてもパッと解決してしまうので。
ですが、この方法はお勧めしません。なぜならアプリケーションのパフォーマンスに悪影響を及ぼすからです。([参考9](#参考))

## 参考
1. [Rails 7 でプロダクト開発を学ぼう - Railsチュートリアル　13章](https://railstutorial.jp/chapters/user_microposts?version=7.0#cha-user_microposts)
2. [Deploy for Free](https://render.com/docs/free#ephemeral-storage)
3. [Dockerでcredentials.yml.encが編集できない時はEditorがインストールされているか確かめる](https://qiita.com/nappyon/items/c00650a2677e9dc6942e)
4. [今日のapt error: Unable to locate package vim](https://qiita.com/kaizen_nagoya/items/f19d94ed241e8d28a56c)
5. [\[Rails\] ActiveStorage + Amazon S3のセットアップ手順をざっくり説明！](https://zenn.dev/kurao/articles/ce8e583450c76e)
6. [Dockerで環境変数を切り替える方法](https://teratail.com/questions/5gjhq06nyq2gnk)
7. [RailsアプリをHeroku Container Registryでデプロイした時の注意点](https://qiita.com/daichi41/items/b1e7c530a2a182e3dddd)
8. [Railsガイド v7.0 config.public_file_server.enabled](https://railsguides.jp/v7.0/configuring.html#config-public-file-server-enabled) 
9. [【2022年版】HerokuでRailsの画像が表示されないときの適切な対処法（と間違った対処法）](https://qiita.com/jnchito/items/3d225112a3ac95379b1d)