この記事を書いた背景・概要
「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
- 今回記述したentrypoint.sh
config/credentials.yml.enc
の編集- 「render.com」で環境変数の設定
- 別途render.comへのデプロイに関して
- JavaScriptが動かない時に
config.assets.compile = 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
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
#!/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が効かなくなってしまった時にしたこと
config/credentials.yml.enc
の編集
下記の様にDockerコンテナ内で、EDITOR=vim bin/rails credentials:edit
として、config/credentials.yml.enc
を開きます。
Dockerコンテナ内でvimが起動しない場合は、(参考3・4)を参照してください。
$ docker compose exec web bash
/myapp# EDITOR=vim bin/rails credentials:edit
下記の様に、それぞれ記述をしてください。「#」がデフォルトで記述されていますが、こちらを付けっぱなしにしておくと、「コメントアウト」と同意なので消してください。また、こちらはymlファイルの為、インデントに要注意です。(参考5)
aws:
access_key_id: アクセスキー
secret_access_key: シークレットアクセスキー
s3:
region: リージョン
bucket: バケット名
config/storage.yml
の編集
下記の様に記述をしてください(参考5)。こちらも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」で環境変数の設定
Railsチュートリアルの設定と違い、ここで必要な設定箇所が2点あります。
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の環境変数をセットする方法で上手く行くかは、実験をしていません。)
- デプロイが上手くいかない時は
Clear build cache & deploy
も試す
今までの設定を行った上で、render.comへのデプロイが上手くいかない場合は、Clear build cache & deploy
でのデプロイも試してみてください。
JavaScriptが動かない時にconfig.assets.compile = true
はやってはいけない
JavaScriptが動かない時に調べていると出てくる、config.assets.compile = true
という情報が出てきますが、この方法はやってはいけないとのこと。私も、最初はこの方法でやっていました😭
config/environments/production.rb の config.assets.compile = false の値を true に変更すれば解決します。この方法はめちゃくちゃ手っ取り早いです。いちいち自分が書いたコードを調べて修正しなくてもパッと解決してしまうので。
ですが、この方法はお勧めしません。なぜならアプリケーションのパフォーマンスに悪影響を及ぼすからです。(参考9)
参考
- Rails 7 でプロダクト開発を学ぼう - Railsチュートリアル 13章
- Deploy for Free
- Dockerでcredentials.yml.encが編集できない時はEditorがインストールされているか確かめる
- 今日のapt error: Unable to locate package vim
- [Rails] ActiveStorage + Amazon S3のセットアップ手順をざっくり説明!
- Dockerで環境変数を切り替える方法
- RailsアプリをHeroku Container Registryでデプロイした時の注意点
- Railsガイド v7.0 config.public_file_server.enabled
- 【2022年版】HerokuでRailsの画像が表示されないときの適切な対処法(と間違った対処法)