render.comにReactとRailsで作成したアプリをデプロイする

オリジナルアプリを作成し、デプロイ先としてrender.comを使用しました。
プログラミングスクールで、Ruby on Railsで作成したアプリをデプロイしたことはありましたが
今回フロントエンドとバックエンドを分けたアプリなので初心者なりに試行錯誤しながら行いました。

## 手順
1.本番環境のDBをpostgreSQLに変更
2.render.comに登録
3.DBを作成
4.web serviceをデプロイ(Rails)
5.static siteをデプロイ(React)


※デプロイ前の前提条件※
- ローカル環境で問題なく動作していること
- Rail apiモードを使用
- Reactはcreatr-react-appで作成していること
- GitHubにコードをpushしていること

開発環境
Ruby 3.2.0
Rails 7.0.0
React 18.3.1
mysql 8.0.40

## 本番環境のDBをpostgreSQLに変更する
renderではpostgreSQLが推奨されているため、本番環境のDBを変更する

```
% brew install postgresql@14
```
ターミナルでpsqlのインストールをする
```ruby:Gemfile
group :production do
  gem 'pg'
end
```
Gemfileの一番下に上記を記載してターミナルでbundle install
Railsのbinフォルダに「render-build.sh」を手動で作成
```ruby
set -o errexit

bundle install
bundle exec rails db:create
bundle exec rails db:migrate
```
本番環境のデータベースを変更する
```ruby:database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  socket: /tmp/mysql.sock

development:
  <<: *default
  adapter: mysql2
  username: root
  password:
  host: localhost
  database: backend_development

test:
  <<: *default
  adapter: mysql2
  username: root
  password:
  host: localhost
  database: backend_test

production:
  <<: *default
  adapter: postgresql
  database: postgresql
  url: <%= ENV['DATABASE_URL'] %>
  username: backend
  password: <%= ENV["BACKEND_DATABASE_PASSWORD"] %>
```
上記のbackend_development,backend_testのbackend部分はrailsのアプリ名になる
```
% bundle lock --add-platform x86_64-linux
```
Gemfile.lockに設定を追加
最新状態をGitHubにpushしておく
## render.comに登録
![スクリーンショット 2024-12-16 20.55.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3690542/56576686-5cf2-4adc-27ec-206c7a3fd0fa.png)
「Get Started for Free」より登録
GitHubで登録し、案内に沿ってメール認証等すれば完了

## DBを作成
右上の「+New」ボタンから「PostgreSQL」を選択する
以下入力
Name: データベース名(なんでも良い、myapp_productionなど)
Region: Ohio
InstanceType: Free

「Create Database」を押す

Statusが「Available」に変わったらデータベースの作成は完了。
登録後の画面で「Internal Database URL」という項目のURLをコピーしておく。(web serviceで使用)

## web serviceをデプロイ(Rails)
DashBoardの右上「+New」を押し、「Web Service」を押す。
GitHubのリポジトリと連携する画面になるため、該当リポジトリを選択し、「Connect →」を押す。
設定を書いていく。

Name: myapp(自分のアプリケーション名)
Region: Ohio(DBに合わせる)
Root Directory: backend(モノレポで１つのリポジトリにbackendとfrontendを入れているため、Railsアプリであるbackendをルートディレクトリに設定した)
Build Command: ./bin/render-build.sh
Start Command: ./bin/rails server
Instance Type: Free

「Environment Variables」に環境変数を設定する
WEB_CONCURRENCY: 2　(公式の設定に従う)
RAILS_MASTER_KEY: donfig/master.keyに書かれている内容をコピペする
DATABASE_URL: DB作成時にコピーした「Internal Database URL」をペースト

「Deploy Web Service」ボタンをクリック

緑の文字でLiveになれば完了
問題があればfailedでログにエラー原因が出力される

![スクリーンショット 2024-12-16 21.21.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3690542/29e014ca-e683-8610-39b2-4cc37f0d7cce.png)

GitHubマークの下にあるhttps://〜〜.render.domがアプリのURL
これがフロントからAPI通信時のエンドポイントURLになる

## static siteをデプロイ(React)
ReactにエンドポイントのURLを設定する
Reactプロジェクトのルートディレクトリに.env.prodcutionを作成
.gitignoreに.env.productionを追加
```js:.env.production
REACT_APP_BASE_URL="render.comのURL"
```
環境変数を設定

render.comのdashborad右上「＋New」で「Static Site」を選択
必要事項を入力していく

Name: アプリ名
Root Directory: front (前項Rails同様、myapp/frontendの構成になっているためルートディレクトリを指定)
Build Command: npm run start
Publish Directory: build

Environment Variablesにエンドポイントの環境変数を追加
REACT_APP_BASE_URL: railsアプリのurl(〜render.comのやつ)

「Create Atatic Site」を押してLiveになれば完成。

React側のURLを押して表示ができているか、railsとのapi通信が問題ないか確認。

## エラーが出た点
```
StandardError: An error has occurred, this and all later migrations canceled: (StandardError)
PG::UndefinedTable: ERROR:  relation "users" does not exist
/opt/render/project/src/backend/db/migrate/20241203042639_create_posts.rb:3:in change'
Caused by:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  relation "users" does not exist (ActiveRecord::StatementInvalid)
/opt/render/project/src/backend/db/migrate/20241203042639_create_posts.rb:3:in change'
Caused by:
PG::UndefinedTable: ERROR:  relation "users" does not exist (PG::UndefinedTable)
/opt/render/project/src/backend/db/migrate/20241203042639_create_posts.rb:3:in change'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
I, [2024-12-12T06:27:20.126586 #152]  INFO -- : Migrating to CreatePosts (20241203042639)
== 20241203042639 CreatePosts: migrating ======================================
-- create_table(:posts)
==> Build failed 😞
```

DB立ち上げ時に、postsテーブルが先に読まれたけどアソシエーションしているusersが存在していないよ！と言われた。
migrationファイルの日付を変えて解決した。

render.comで作成したDBをリセットするには、.bin/build-render.shを以下に変更して再デプロイする
```
# bundle exec rake db:migrate
DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:migrate:reset
```
終わったら、コメントアウトを外し、最後の行は消しておく

## まとめ

自分が調べた範囲では日本語でのデプロイ記録がほとんどなかったので
利用したい方にとって参考になれば嬉しいです。

## 参考文献
https://community.render.com/t/how-to-set-up-app-with-rails-backend-and-react-frontend/8973

https://note.com/o_ob/n/naa0a7dc70afc

https://medium.com/@tivyh112/deploying-a-rails-api-only-app-on-render-24370ae06a1f

https://medium.com/@tivyh112/deploying-a-rails-api-only-app-on-render-24370ae06a1f

https://github.com/learn-co-curriculum/phase-4-deploying-rails-react-to-render?tab=readme-ov-file

https://dev.to/nickmendez/heroku-alternative-how-to-deploy-a-reactjs-rails-api-app-to-render-2k17?utm_source=dlvr.it&utm_medium=twitter

https://zenn.dev/rinda_1994/articles/389de8766e4584

大変お世話になりました。