Dockerを使用してRailsアプリをRenderへデプロイした

この記事は、Dockerを使用してReilsアプリをRenderへデプロイしたいが、エラーが出てデプロイできていない方向けの記事です。

### 環境
Rails 7.2.1
Ruby 3.2.0
PostgreSQL
Dockerを使用

### フォルダ・ファイル構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426016/9924e9b7-2d70-3eda-1838-659e929025fc.png)
※Dockerfileはrailsapp内にもう一つあります。

### 結論下記の内容でデプロイに成功した。
```render.yaml
services:
  - type: web
    name: compassbook
    env: ruby
    rootDirectory: railsapp
    buildCommand: |
      echo "Starting build process..."
      bundle install
      yarn install
      rails assets:precompile
      echo "Build completed."


```

下記、railsapp/Dockerfile
```railsapp/Dockerfile
# syntax = docker/dockerfile:1

# ベースイメージの指定
ARG RUBY_VERSION=3.2.0
FROM ruby:$RUBY_VERSION-slim AS base

# 作業ディレクトリの設定
WORKDIR /rails

# 必要なパッケージのインストール
RUN set -eux; \
    apt-get update -qq; \
    until apt-get install --no-install-recommends -y \
        curl \
        libpq-dev \
        libjemalloc2 \
        libvips \
        git; do \
      echo "apt-get install failed, retrying in 5 seconds..."; \
      sleep 5; \
      apt-get update -qq; \
    done; \
    rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*

# 環境変数の設定
ENV RAILS_ENV=production \
    BUNDLE_DEPLOYMENT=1 \
    BUNDLE_PATH=/usr/local/bundle \
    BUNDLE_WITHOUT=development

# ビルドステージの開始
FROM base AS build

# ビルドに必要なパッケージのインストール
RUN set -eux; \
    apt-get update -qq; \
    until apt-get install --no-install-recommends -y \
        build-essential \
        libpq-dev \
        git \
        node-gyp \
        pkg-config \
        python-is-python3; do \
      echo "apt-get install failed, retrying in 5 seconds..."; \
      sleep 5; \
      apt-get update -qq; \
    done; \
    rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*

# Node.js と Yarn のインストール
ARG NODE_VERSION=20.17.0
ARG YARN_VERSION=1.22.22
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
    /tmp/node-build-master/bin/node-build "$NODE_VERSION" /usr/local/node && \
    npm install -g yarn@$YARN_VERSION && \
    rm -rf /tmp/node-build-master

# アプリケーションの Gem をインストール
COPY Gemfile Gemfile.lock /rails/
RUN bundle install && \
    rm -rf ~/.bundle/ "$BUNDLE_PATH"/ruby/*/cache "$BUNDLE_PATH"/ruby/*/bundler/gems/*/.git

# Node.js の依存関係をインストール
COPY package.json yarn.lock /rails/
RUN yarn install --frozen-lockfile

# アプリケーションコードをコピー
COPY . /rails

# Bootsnap のプリコンパイルと権限設定
RUN bundle exec bootsnap precompile app/ lib/
RUN chmod +x ./bin/rails

# アセットのプリコンパイル
ARG DATABASE_URL
ARG SECRET_KEY_BASE
ENV DATABASE_URL=$DATABASE_URL
ENV SECRET_KEY_BASE=$SECRET_KEY_BASE
RUN DATABASE_URL=$DATABASE_URL RAILS_ENV=production SECRET_KEY_BASE=$SECRET_KEY_BASE bundle exec rails assets:precompile

# 不要な Node.js モジュールを削除（任意）
RUN rm -rf node_modules

# 最終ステージの開始
FROM base

# ビルド済みのアーティファクトをコピー
COPY --from=build "$BUNDLE_PATH" "$BUNDLE_PATH"
COPY --from=build /rails /rails

# ファイルの所有権とパーミッションを設定
RUN groupadd --system --gid 1000 rails && \
    useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
    chown -R rails:rails /rails

USER rails

# 作業ディレクトリの設定
WORKDIR /rails

# 環境変数の設定
ENV RAILS_ENV=production

# ポートの公開
EXPOSE 3000

# CMD の設定
CMD ["bash", "-c", "bundle exec rails db:migrate && bundle exec rails server -b 0.0.0.0 -p 3000"]

```

### デプロイポイント
#### その1 無料で使うならPostgreSQL
はじめ、MySQLでRailsアプリを使っていたが、Renderで用意されているDBはPostgreSQLでした。MySQLはなし。
MySQLからPostgreSQLに変更しても問題ないことを確認し、PostgreSQLに変更しました。
Railsアプリをポートフォリオとして作成し無料で使えるデプロイ先を探す場合、Herokuが有料化されたことにより、無料デプロイ先はRenderになるかと思われる。そんなかたは、最初からPostgreSQLを使ってRailsアプリを作成することをお勧めする。

#### その2 Exited with status 128というエラー
下記、デプロイ終わりごろのExited with status 128というエラー
```
Pushing image to registry...
Upload succeeded
DONE
==> Deploying...
==> Exited with status 128
==> Common ways to troubleshoot your deploy: https://docs.render.com/troubleshooting-deploys
```
「Exited with status 128」の一行しか表示されず、詳細なログが確認できないため何の原因でこのエラーが出ているのか分かりにくい。

結論として、Gemfileやアプリケーションコードのコピー先パスが間違っていたことが原因のようだ。
Dockerを使用していることにより、Renderで下記の設定をしている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426016/4fa08189-a235-4e24-1129-cf8284ebff36.png)
railsappフォルダをルートディレクトリとしている。

railsapp内のDockerfileで下記、(Renderでの作業フォルダ)railsフォルダを作業フォルダにしている。
```
# 作業ディレクトリの設定
WORKDIR /rails
```

railsappフォルダとrailsフォルダがあり、さらにルートディレクトリをrailsappとしていたことで、コピー元先のファイルパスに誤りが出てしまった。

### まとめ
デプロイで困っている方にこの記事が参考になれば幸いです。