6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DockerでRails + PostgreSQLの開発環境構築~Renderでデプロイまで

6
Last updated at Posted at 2025-12-17

はじめに

こんにちは。RUNTEQにて学習中のかるめと申します。

今回はDockerを用いてRails + PostgreSQLの開発環境を構築し、Renderにデプロイするまでの記事となります。類似記事は既に多くありますが、開発環境構築からデプロイまでの流れを載せている記事は少なく感じたのと、個人的なアウトプット目的の意味合いもかねて書いておきます。

「よく分かってないけど、とりあえずDockerfileやcompose.yamlをコピペして開発環境を作ってる」という初心者を意識して説明も添付しています。

学習中の身のため、何か間違いなどありましたらご指摘いただけると幸いです。

基本情報

Ruby: 3.4.7
Ruby on Rails: 7.2.3
JavaScriptのバンドラー: importmap または esbuild
CSSフレームワーク: Tailwind CSS または Bootstrap
データベース: PostgreSQL 16
デプロイ先: RenderのRuby環境

開発環境構築の手順

開発環境を構築するおおまかな流れは以下のようになります。

  1. 開発用ディレクトリを作成&移動
  2. Dockerfile.dev、compose.yaml、Gemfileを作成&編集
  3. rails new
  4. config/database.yamlを編集
  5. Procfile.devを編集
  6. ビルド&データベース準備
  7. docker compose upを実行

以下から順に進めていきます。

1. 開発用ディレクトリを作成&移動

プロジェクトを置くディレクトリを作成して、そこに移動します。

ターミナル
mkdir myapp && cd $_

2. Dockerfile.dev、compose.yaml、Gemfileを作成&編集

開発環境用のDockerfileであるDockerfile.dev、compose.yaml、Gemfile、Gemfile.lockをそれぞれ作成します。

ターミナル
touch Dockerfile.dev compose.yaml Gemfile Gemfile.lock

Gemfile

以下のように編集します。

Gemfile
source "https://rubygems.org"
gem "rails", "7.2.3"

空のGemfile.lockを用意しておくことで、この後のdocker compose buildコマンドを実行時の「Gemfile.lock が見つからない」というエラーを回避できます。

Dockerfile.dev

Rails7.1以降では、この後のrails newコマンド実行時に本番環境用のDockerfileが自動生成されます。そのため開発環境用としてDockerfile.devという名前で別に用意します。使いたいCSSフレームワークに合わせて編集します。

追記
必要なものがあれば追加でインストールしましょう。Dockerfile.devのRUN命令のインストール部分に追加すればOKです。
例1:コンテナ内でconfig/credentials.yml.encを編集するためにVimをインストールする
例2:Active Storageのvariant機能を使うためにlibvipsをインストールする

Tailwind CSSを使う場合

JavaScriptのバンドラーはデフォルトのimportmapで大丈夫なのでNode.jsやYarnをインストールする必要はありません。以下のように編集します。

Dockerfile.dev
FROM ruby:3.4.7
ENV LANG C.UTF-8
ENV TZ Asia/Tokyo
ENV RAILS_ENV=development
RUN apt-get update -qq && apt-get install -y \
	build-essential \
	libpq-dev \
	&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
Dockerfile.devの説明
Dockerfile.dev
FROM ruby:3.4.7  # ベースイメージのバージョンを指定
ENV LANG C.UTF-8  # 日本語の文字化け防止
ENV TZ Asia/Tokyo  # コンテナ内のタイムゾーンをJSTに設定して、デバッグ時のログの時刻をわかりやすくする
ENV RAILS_ENV=development  # 開発環境であることを明示
RUN apt-get update -qq && apt-get install -y \  # installする前にupdateする、-qqでログの出力を抑制する
	build-essential \  # 必須
	libpq-dev \  # PostgreSQLを使う場合は必須
	&& rm -rf /var/lib/apt/lists/*  # クリーンアップ処理
WORKDIR /app  # 作業ディレクトリの指定
COPY Gemfile Gemfile.lock ./  # Gemfileだけ先にコピー(キャッシュ効率化)
RUN bundle install  # Gemに関連するファイルだけインストール
COPY . .  # ローカルのディレクトリを丸ごと作業ディレクトリにコピー

Bootstrapを使う場合

esbuildというJavaScriptのバンドラーを使用します。そのため、Node.jsやYarnのインストールが必要となります。以下のように編集します。

Dockerfile.dev
FROM ruby:3.4.7
ENV LANG C.UTF-8
ENV TZ Asia/Tokyo
ENV RAILS_ENV=development
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - \
&& apt-get update -qq \
&& apt-get install -y \
    build-essential \
    libpq-dev \
    nodejs \
&& npm install --global yarn \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
Dockerfile.devの説明(1つ前の説明との差異のみ)
Dockerfile.dev
FROM ruby:3.4.7
ENV LANG C.UTF-8
ENV TZ Asia/Tokyo
ENV RAILS_ENV=development
# Node.jsは公式リポジトリを追加してからインストール、Yarnはnpm経由でインストール
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - \
&& apt-get update -qq \
&& apt-get install -y \
    build-essential \
    libpq-dev \
    nodejs \
&& npm install --global yarn \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .

compose.yaml

以下のように編集します。

compose.yaml
services:
  web:
    build:
      context: .
      dockerfile: "Dockerfile.dev"
    ports:
      - "3000:3000"
    command: bash -c "rm -f tmp/pids/server.pid && ./bin/dev"
    tty: true
    stdin_open: true
    environment:
      - TZ=Asia/Tokyo
    depends_on: 
      db: 
        condition: service_healthy
    volumes:
      - .:/app
      - bundle_data:/usr/local/bundle

  db: 
    image: postgres:16
    ports:
      - "5432:5432"
    environment:
      POSTGRES_PASSWORD: password
    restart: always
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  bundle_data:
  postgres_data: 
compose.yamlの説明
compose.yaml
services:
  web:
    # 開発環境では ./Dockerfile.dev からビルドする
    build: 
      context: .
      dockerfile: "Dockerfile.dev"
    ports:
      - "3000:3000"  # 開発環境では3000番ポートでアプリケーションにアクセス
    # クリーンアップ処理&Procfile.devを起動
    command: bash -c "rm -f tmp/pids/server.pid && ./bin/dev"
	tty: true  # デバッグコマンドを使えるようにする
    stdin_open: true  # デバッグコマンドを使えるようにする
    environment:
      - TZ=Asia/Tokyo  # デバッグ時に時間を見やすくする
    # 接続エラーを防ぐためにdbコンテナが起動確認後にwebコンテナを起動する
    depends_on: 
      db: 
        condition: service_healthy
	volumes:
      - .:/app  # バインドマウント
      - bundle_data:/usr/local/bundle  # bundleキャッシュ
  
  db: 
    image: postgres:16  # PostgeSQLイメージのバージョンを指定
    ports:
      - "5432:5432"  # 開発環境ではポート公開
    # POSTGRES_PASSWORDは必須
    environment:
      POSTGRES_PASSWORD: password
	restart: always  # DBは安定稼働させる
    healthcheck:  # restartとセットで使う
      test: ["CMD-SHELL", "pg_isready -U postgres"]  # PostgreSQLの接続確認コマンド
      interval: 10s  # チェック間隔
      timeout: 5s  # コマンドのタイムアウト時間
      retries: 5  # unhealthyになるまでのリトライ回数
      start_period: 30s  # 初回起動時の猶予期間
    volumes:
      - postgres_data:/var/lib/postgresql/data  # ボリュームマウント

volumes:
  bundle_data:
  postgres_data: 

補足:PostgreSQL 18以降のボリュームマウント先について
今回の記事のようにPostgreSQL 17以前の場合は/var/lib/postgresql/dataとなりますが、PostgreSQL 18以降を使う場合は/var/lib/postgresqlとしてください。
参考:Docker Hubの公式ページ

compose.yamlとこの後のDatabase.yamlでは、開発環境のための簡易的な設定として平文のパスワードを使っています。

3. rails new

こちらも使いたいCSSフレームワークに合わせてコマンドを実行します。

rails newのオプションについて

rails newする際に、使用するデータベースやJavaScriptのバンドラー、CSSフレームワークを指定します。

データベース
既定値はSQLite。PostgreSQLを使用したい場合は -d postgresql と指定します。

JavaScriptのバンドラー
既定値はimportmap。TypeScriptやReact、VueなどのUIライブラリを使いたい場合はesbuildなどのバンドラーを指定します( -j esbuild)。importmap以外を使う場合はDockerfileでNode.jsとYarnのインストールが必要です。

CSSフレームワーク
Tailwind CSSを使用したい場合は--css=tailwind、Bootstrapを使用したい場合は--css=bootstrapのオプションをつけます。

Tailwind CSSを使う場合

ターミナル
docker compose run --rm web rails new . --force --database=postgresql --css=tailwind

Bootstrapを使う場合

ターミナル
docker compose run --rm web rails new . --force --database=postgresql -j esbuild --css=bootstrap

rails newした後に出てくる警告について
Bootstrapを使う場合は、rails new後にSassの警告が大量に出てきます。一応そのままでも動きますが、気になる方は修正しましょう。

4. config/database.yamlを編集

# 以下3行を追加しますとコメントしている以下の部分を追加してください。

config/database.yaml
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # https://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  # 以下3行を追加します
  host: db
  username: postgres
  password: password
  
development:
  <<: *default
  database: app_development
  
test:
  <<: *default
  database: app_test
    
production:
  <<: *default
  # Renderでは環境変数DATABASE_URLが優先されるため、以下の設定は使用されません
  database: app_production
  username: app
  password: <%= ENV["APP_DATABASE_PASSWORD"] %>

5. Procfile.dev

Procfileはforemanというgemを使っています。compose.yamlのcommandで./bin/devと実行させることで、Procfileがjsやcssもまとめてビルドしてくれて、開発中にファイルの変更内容が自動反映されます。

Tailwind CSSを使う場合

importmapの場合、jsのビルドは不要です。

Procfile.dev
web: bin/rails server -b 0.0.0.0 -p 3000
css: bin/rails tailwindcss:watch

Bootstrapを使う場合

Procfile.dev
web: bin/rails server -b 0.0.0.0 -p 3000
js: yarn build --watch
css: yarn watch:css

6. ビルド&データベース準備

ビルドとデータベースの準備を行います。

ターミナル
docker compose build
ターミナル
docker compose run --rm web bundle exec rails db:prepare

7. docker compose upを実行

ターミナル
docker compose up

これで開発環境ができました。http://localhost:3000にアクセスするといつもの画面が表示されるはずです。

デプロイ手順

これからRenderでのデプロイ手順を紹介していきます。開発環境ができたばかりの方は確認画面をscaffoldでも大丈夫なので作成しておいてください。

以下の流れで進めていきます。

  1. bin/render-build.shを作成&編集
  2. GitHubにpush
  3. 本番環境用のPostgreSQLを作成
  4. Web Serviceを作成

1. bin/render-build.shを作成&編集

ビルド時に実行するシェルスクリプトを作成します。

ターミナル
touch bin/render-build.sh

デフォルトでは実行権限が無いので追加しておきます。

ターミナル
chmod a+x bin/render-build.sh

以下のように編集します。

bin/render-build.sh
#!/usr/bin/env bash
set -o errexit

bundle install
bundle exec rails assets:precompile
bundle exec rails assets:clean

bundle exec rails db:migrate
初期データを入れたい場合

bundle exec rails db:seedを追加する。

bin/render-build.sh
#!/usr/bin/env bash
set -o errexit

bundle install
bundle exec rails assets:precompile
bundle exec rails assets:clean

bundle exec rails db:migrate
bundle exec rails db:seed

2. GitHubにpush

1が終わったらリモートリポジトリにpushしておきます。

3. 本番環境用のPostgreSQLを作成

これからはRenderで作業をしていきます。

Renderにアクセスして、Add newボタンからPostgresを選択を選択します。作成画面を開いたら以下を設定します。

設定項目 設定内容
Region Singapore
PostgreSQL Version 使用するバージョン(今回は16)
Instance Type Free(無料プラン)

その他はお好みで大丈夫です。設定できたらCreate Databaseボタンを押しましょう。

しばらく待つとできあがります。できあがったら表示されるinternal database URLをこのあと使用します。

4. Web Serviceを作成

最後にRailsアプリをデプロイするためのWeb Serviceを作成します。

Add newボタンを押して、今度はWeb Serviceを選択します。Source Codeを選ぶ画面が出るので、今回デプロイするリポジトリを選択します。設定画面が出てくるので以下のように設定します。

設定項目 設定内容
Language Ruby
Branch デプロイしたいブランチ
Region Singapore
Instance Type Free(無料プラン)
Build Command ./bin/render-build.sh
Start Command bundle exec puma -C config/puma.rb

Languageの設定について
LanguageにはデフォルトでDockerと入っていますが、今回はマネージドなRuby環境にデプロイするため、チェックボックスからRubyと選択します。

このため、今回は自動生成された本番環境向けのDockerfileとそこから実行されるbin/docker-entrypointは使用しません。これらはRenderのDockerモードやその他コンテナサービスにデプロイする場合に使用します。

ちなみにDockerと設定したままだとBuild CommandとStart Commandが表示されません。

上記の設定が終わったら、Environment Variablesで環境変数を設定します。

NAME_OF_VARIABLE value
WEB_CONCURRENCY (デフォルトで入っているものでOK)
RAILS_MASTER_KEY (ローカルのconfig/master.keyの値)
RAILS_ENV production
DATABASE_URL (PostgreSQLのInternal Database URLの値)

環境変数の入力が終わったら、すぐ下のAdvancedをクリックして展開します。Health Check Pathを設定しておきましょう。デフォルトでは/upなのでそのまま入れます(Railsのルーティングで設定変更できます)。

全ての設定ができたらDeploy Web Serviceボタンをクリックします。

あとはLogを見守りましょう。ビルドやデプロイができているか確認できます。デプロイが成功したら、RenderのダッシュボードからアプリのURLにアクセスして動作確認をしましょう。開発した通りに表示されていれば成功です!細かいミスをしていてデプロイが失敗していても、修正してデプロイし直せばOKです。お疲れ様でした。

参考

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?