2
2

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 全部地雷だった件|構築〜起動まで完全ロードマップ

Last updated at Posted at 2025-08-09

はじめに

Railsの環境構築、甘く見てました。

Docker × Rails × PostgreSQL の組み合わせでアプリを立ち上げるまで、
何度も地雷を踏み、何度もエラーに泣かされ、何度も心が折れかけました。

この記事では、そんな僕が実際に踏んだエラーとその解決策を含めて、
初期構築からサーバー起動までの手順を完全にまとめました

「最短で立ち上げたい」
「もうハマりたくない」
そんな人の役に立てたら嬉しいです。

実施したこと

要約

既存のRailsアプリをGitHubからクローンし、Docker ComposeとPostgreSQLを使ってDocker環境を構築しました。

詳細

  • GitHubのテンプレートから docker_rails リポジトリを作成
  • 作成したリポジトリをローカルにクローン
  • ローカルで docker ブランチを作成し変更
  • 以下のファイルを新規作成・編集し、Docker環境を構築
    • 新規作成
      • Dockerfile
      • Gemfile
      • Gemfile.lock
      • docker-compose.yml
    • 編集
      • config/detabase.yml
  • docker compose up --build でアプリを起動し、ブラウザで表示を確認
  • 変更内容を GitHub にプッシュし、プルリクエストを作成

開発環境

  • macOS Sequoia
  • Docker version 28.3.2
  • Docker Compose version v2.38.2
  • ruby 3.4.5
  • Rails 8.0.2
  • PostgreSQL version 12

ファイル構成

rails_docker/
├── .github/workflows/docker.yml
├── Dockerfile
├── docker-compose.yml
├── Gemfile
├── Gemfile.lock
├── config/
│   ├── application.rb
│   ├── boot.rb
│   ├── database.yml 
│   └── environment.rb

完成形を見たい方はこちら

すぐに動くコードだけ見たい方は、以下を参考にしてください。
完成系はこちら

Docker環境構築手順とエラー対応

Docker環境構築手順

1. 事前準備フェーズ:環境確認とリポジトリ準備
2. 基礎ファイル作成フェーズ:構築ファイルの準備
3. DB設定フェーズ:接続設定

エラー対応フェーズ

4. secret_key_base エラー
5. bootsnap/setup 読み込みエラー
6. config.assets 関連エラー(Rails8非対応設定)
7. postgresql アダプタ読み込みエラー(pg gem不足)
8. puma gem不足エラー
9. migrate未実行エラー
10. javascript_importmap_tags 未定義エラー

Docker環境構築手順とエラー対応詳細

1. 事前準備フェーズ:環境確認とリポジトリ準備

まずは、Docker と Docker Compose がインストールされているかを確認します。

docker -v

docker compose version

続いて、GitHub から Rails アプリをローカルにクローンします

git clone https://github.com/rai-code11/rails-docker.git 

Gitは リポジトリ名と同じ名前のフォルダ rails-docker/ を自動生成してその中にクローンしますが、下記のようにディレクトリを指定すると任意のディレクトリ名をつけそこにクローンすることができます

git clone https://github.com/rai-code11/rails-docker.git rails_docker

これでrails_docker/という名前のディレクトリができ、そこが.gitを含むクローン先になります
rails_dockerディレクトリに移動します

cd rails_docker

dockerブランチを切ってブランチを変更します

git checkout -b ブランチ名

現在のブランチを確認するには、以下のコマンドを使用します

git branch

2. 基礎ファイル作成フェーズ:構築ファイルの準備

以下のコマンドで、必要なファイルを作成します

touch Dockerfile Gemfile Gemfile.lock

まずdockerfileから記述します

code Dockerfile

Dockerfile

アプリケーションを動かすための環境(OS・ライブラリなど)を定義したファイル。コンテナを作るための設計書です。

FROM ruby:3.4.5
RUN apt-get update -qq && apt-get install -y \ 
nodejs \
postgresql-client \
yarn
WORKDIR /rails_docker
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
  • FROM:どのイメージを使うか?
    今回はRuby 3.4.5 の公式イメージを使って、アプリの土台を作ります。

  • RUN:ベースイメージ(例:ruby:3.4.5)から一時的なコンテナを作り、その中で RUN に書かれたコマンドを実行します。実行結果(ファイル変更など)を「新しいイメージのレイヤー」として保存し、コンテナから抜けます。

    • 今回実行されるコマンド

      • apt-get update -qq

        • apt-get update
          • 最新のパッケージリストを取得します
        • -qq(quiet quiet)
          • 通常の apt-get update は大量にミラーURLや取得情報を表示するが、-qq だと必要最低限しか出ません
      • apt-get install -y

        • apt-get install
          • 指定したパッケージをインストールする
            • 今回必要なパッケージ
              • nodejs:JavaScript動作用(RailsでJSを使う)
              • postgresql-client:PostgreSQLに接続するためのクライアントツール
              • yarn:JavaScriptパッケージ管理ツール(Webpackerやjsbundlingで使用)
        • -y
          • インストール時の「続行しますか? [Y/n]」という確認を自動的にYesで回答
          • Dockerビルドは非対話的に進める必要があるため必須です
      • 下記のように&&でコマンド同士を繋げることができます
        RUN apt-get update -qq && apt-get install -y

  • WORKDIR /rails_docker
    これ以降のコマンドを/rails_dockerディレクトリで動作させる設定です

  • COPY Gemifile Gemfile.lock ./
    GemifileとGemfile.lockファイルをコンテナの/rails_dockerディレクトリにコピーします

  • RUN bundle install
    Gemツールをインストールします

  • COPY . .
    ホストのカレントディレクトリをコンテナ内の/rails_dockerファイル内にコピーします

補足

RubyとRailsのバージョンの互換性はこちらで確認できます

railsの最新バージョン確認コマンド
RubyGems.org に公開されている "rails" という名前の gem の全バージョン一覧を取得するためのコマンド

gem search ^rails$ --remote --all

コマンドの意味

  • gem search
    RubyGems にある gem を検索するコマンド。

  • ^rails$「行の先頭から末尾までが ちょうど rails だけのものに一致」

    • ^ → 文字列の先頭
      • ^rails「railsで始まる」すべての文字列が一致
    • rails → 検索対象文字列
    • $ → 文字列の末尾
      • rails$「railsで終わる」すべての文字列が一致
  • --remote
    ローカルにインストールされている gem ではなく、RubyGems.org(リモート)上で検索するという指定。

  • --all
    対象 gem のすべてのバージョンを表示するオプション。
    これがない場合は最新の安定版しか表示されない。

表示結果

*** REMOTE GEMS ***

rails (8.0.2, 8.0.1, 8.0.0.1, 8.0.0, 7.2.2.1, 7.2.2, 7.2.1.2, 7.2.1.1, 7.2.1, 7.2.0, 7.1.5.1, 7.1.5, 7.1.4.2, 7.1.4.1, 7.1.4, 7.1.3.4, 7.1.3.3, 7.1.3.2, 7.1.3.1, 7.1.3, 7.1.2, 7.1.1, 7.1.0, 7.0.8.7, 7.0.8.6, 7.0.8.5, 7.0.8.4, 7.0.8.3, 7.0.8.2, 7.0.8.1, 7.0.8, 7.0.7.2, 7.0.7.1, 7.0.7, 7.0.6, 7.0.5.1, 7.0.5, 7.0.4.3, 7.0.4.2, 7.0.4.1, 7.0.4, 7.0.3.1, 7.0.3, 7.0.2.4, 7.0.2.3

最新が8.0.2であることがわかります

  • railsの最新バージョン確認サイト

  • Rubyの最新バージョン確認サイト

次にGemfileを記述します

Gemfile

Rails やその他必要な Ruby ライブラリ(=gem)を記載するファイル
「何の gem が必要か」を定義し、bundle install コマンドで使います

source 'https://rubygems.org'

ruby "3.4.5" 

gem 'rails', '~> 8.0.2'
  • source 'https://rubygems.org'
    • gem(Rubyライブラリ)の取得元を指定します
    • https://rubygems.orgは公式のgem配布サイトです
  • ruby "3.4.5"
    • このアプリが動作する Ruby のバージョンを指定します
    • BundlerやRailsは、この記述を見て指定バージョンのRubyが必要ですと判断します

Gemfileの ruby と Dockerfileの FROM は 必ず一致させましょう

  • gem 'rails', '~> 8.0.2'
    • rails という gem をインストール
    • ~> 8.0.2 はバージョン指定
      • ~> は楽観的なバージョン指定
      • 8.0.2 以上 かつ 8.1.0 未満のバージョンを許可する

Gemfile.lock

Gemfile を元に bundle install したときに、自動生成されるロックファイル。

docker-compose.ymlファイルを記述します

docker-compose.yml

複数のコンテナの設定を1つにまとめて書けるファイルです。
実際のコンテナ(Rails用・DB用など)は別々に作られますが、このファイルを使えばまとめて起動・停止・管理ができるようになります。

version: '3'
services:
  db:
    image: postgres:12
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password

  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
  • 共通設定

    • version: '3'Composeファイルのバージョン。'3'は安定して使われる一般的なバージョンです
    • services:ここに記述した名前(例:web、db)がコンテナ名の識別子になります
      • 基本的に1サービスにつき1コンテナが推奨されています
  • データベースの設定

    • image: postgres:12:dbのイメージにはpostgres:12を使います
    • environment:環境変数には、dbのユーザー名とパスワードを設定します
      • POSTGRES_USER: postgres
      • POSTGRES_PASSWORD: password
  • Railsの設定

    • build: .:Dockerfileが存在するカレントディレクトリを指定してビルドを行いDockerfileからイメージを作成します

    • command:その後、下記のコマンドを実行します

    • bundle exec rails s -p 3000 -b '0.0.0.0'

      • bundle exec

        • Bundler 経由でコマンドを実行する。
        • Gemfile.lock に書かれたバージョンの gem を優先的に使うので、環境差異やバージョン違いによるエラーを防げる。
      • rails s

        • rails server の短縮形。
        • Rails アプリの開発用 Web サーバーを起動する
      • -p 3000

        • ポート番号を指定
        • ブラウザから http://localhost:3000 でアクセスできるようにする
      • -b '0.0.0.0'

        • バインドアドレスを指定:サーバーが起動時に「どのIPで待ち受けるか」を指定
        • 0.0.0.0 は「すべてのネットワークインターフェースで待ち受ける」という意味
        • Dockerや仮想環境でホストからアクセス可能にするために必要(デフォルトの localhostだと外から繋げない)
    • volumes:ローカルのカレントディレクトリをコンテナ内の/myappディレクトリにマウントして、同期します
      コンテナから中身が見えて編集もできますが、ソースコードはホスト側にあります

    • ports:- "3000:3000":ホストとコンテナのポートを繋げてインターネットがコンテナ内まで届くようにします

    • depends_on:dbdocker compose upで起動した際のサービスの起動順の制御をします。dbと記述することでdbが起動してからweb:Railsが起動します

3. DB設定フェーズ:接続

detabase.yml

Railsアプリが、「どのデータベースに」「どうやってつなぐか」を指定するファイルです。このファイルは、環境ごと(development / test / production)にデータベースの接続情報を定義します。(docker-compose.ymlと一致させる)

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password   
  pool: 5

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test
  • adapter: postgresql
    使用するデータベースの種類を指定。今回は、PostgreSQLを指定します

  • encoding: unicode
    データベースの文字コードを設定します

  • host: db
    DBサーバーのホスト名を記述します。ここで指定している db は、docker-compose.yml におけるサービス名です
    Dockerネットワーク上では、サービス名=ホスト名として解決されるため、db と書けばそのコンテナに接続できます

  • username: postgres
    PostgreSQLにログインするためのユーザー名です。docker-compose.yml の中で指定していれば、それと一致させる必要があります

  • password: password
    PostgreSQLのログインパスワード。
    こちらも docker-compose.yml で環境変数として渡します

  • pool: 5
    DB接続の同時最大数

  • development: <<: *default database: myapp_development
    <<: *default は「defaultセクションの設定をすべて読み込む」という意味

    • database: myapp_development は「開発用のDBの名前」を指定。
      PostgreSQLコンテナ内に「myapp_development」という名前のDBが作成され、Railsがそれに接続する。
  • test: <<: *default database: myapp_test
    テスト環境専用のDBを指定します
    RSpecやMinitestなどでテストを実行すると、Railsは自動的にこの test 設定を使用し、myapp_test データベースに接続します

docker compose up

エラー発生
Missing secret_key_base for 'production' environment

本番環境のための秘密鍵がありません

  • docker-composefile.yml内でRAILS_ENVを指定しない場合、Railsはデフォルトでproduction(本番モード)で起動するそうです。しかし、本番モードでは secret_key_baseの設定が必須だったため、未設定だと起動時にエラーになります

2つの解決方法

  • secret_key_baseが不要な開発モードかテストモードで起動する
  • secret_key_baseを設定して本番モードで起動する

今回は、①の解決方法で解決します

docker-compose.ymlwebサービスに以下を追加:

services:
  web:
    environment:  #追加
      - RAILS_ENV=development  #development(開発)追加

一応解決方法②も書いておきます
本番モードのままsecret_key_baseを設定します

docker-compose.ymlwebサービスに以下を追加:

services:
  web:
    environment:  #追加
      - RAILS_ENV=production  #production(本番)追加
      - SECRET_KEY_BASE=あなたのキー文字列  #追加

今回は、開発モードで起動するために環境変数RAILS_ENVdevelopmentを設定しました

version: '3'
services:
  db:
    image: postgres:12
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password

  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
    environment:  #追加
      RAILS_ENV: development   #追加
docker compose up

Railsのコンテナ内にデータベースを作成します

docker compose exec web rails db:create

エラー発生
LoadError: cannot load such file -- bootsnap/setup

bootsnap/setupというファイルを読み込めない

Gemfilegem 'bootsnap'を追加

gem 'bootsnap'

しかし、gemfileにこれだけを書くと
Rails(boot.rb)の中にすでに下記のコードがあるため二重ロードになったり、タイミングがバラけてエラーになることがあります

require "bootsnap/setup"

これはアプリケーション起動時に手動で bootsnap を読み込む設定です

それに対して、Gemfile にこう書くと…

gem 'bootsnap'
Bundler(gemの管理システム)が自動的にアプリ起動時に require 'bootsnap' しようとします。

しかし、すでにboot.rbrequire しているので、「この gem は読み込まないで(requireしないで)」と指示することでboot.rbの手動読み込みだけが有効になり、エラー回避に繋がるそうです。

Gemfile:Gemを使う宣言 → Gemをインストールできるようにする

boot.rb:Gemを実際に使う(読み込む)処理

require: false:手動で読み込むなら、自動読み込みはオフにしておく

Gemfileにgem 'bootsnap', require: falseを追加:

code Gemfile
ruby '3.4.5'
gem 'rails', '~> 8.0.2'
gem 'bootsnap', require: false  #追加

Gemfileを編集したので再ビルドして起動します。再ビルドして起動は下記のコマンドで一括でできるので今後はこちらのコマンドを使っていきます。

docker compose build
docker compose up 
↓短縮系
docker compose up --build
docker compose exec web rails db:create

エラー発生
NoMethodError: undefined method `assets' for an instance of Rails::Application::Configuration

NoMethodError: Rails::Application::Configurationのインスタンスにはassetsというメソッドは定義されていません

これはRails7以前の設定ファイルにだけ存在していたconfig.assetsという設定がRails8では削除されたために起きるエラーです

Rails 8.0からはsprocketsを標準で使わない(=config.assetsは使えない)そうです。そのため、Rails 8ではconfig.assets自体が削除されています

そのためconfig.assetsを削除します

削除する場所を探します
config内のconfig.assetsと書かれている項目をすべて抽出します

grep -rn "config.assets" config/

オプションの意味

  • -r 再帰的にサブフォルダも検索(config/配下すべて)
  • -n 該当行の行番号を表示
  • "config.assets" この文字列を含む行を探す
config/environments/production.rb:28:config.assets.css_compressor = :sass
config/environments/production.rb:31:config.assets.compile = false
config/environments/development.rb:60:config.assets.quiet = true
config/initializers/assets.rb:4:Rails.application.config.assets.version = "1.0"
config/initializers/assets.rb:7:Rails.application.config.assets.paths << Emoji.images_path
config/initializers/assets.rb:12:Rails.application.config.assets.precompile += %w( admin.js admin.css )

それぞれのファイルを開いて上記の項目をコメントアウトします

code config/environments/production.rb config/environments/development.rb config/initializers/assets.rb
# config.assets.css_compressor = :sass
# config.assets.compile = false
# config.assets.quiet = true
# Rails.application.config.assets.version = "1.0"
# Rails.application.config.assets.paths << Emoji.images_path
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
docker compose exec web rails db:create

エラー発生
NoMethodError: undefined method `assets' for an instance of Rails::Application::Configuration

また同じエラーでた、、、、、

反映させるために起動中のコンテナ群とネットワーク・ボリュームをまとめて停止&削除します

docker compose down

続けて、tmp/ ディレクトリを削除します
tmp/は、Railsがキャッシュやセッション、一時ファイルなどを保存している場所です
Railsが古いキャッシュを使ってバグることがあるので、削除してクリーンな状態にします

rm -rf tmp/* 

Dockerイメージをキャッシュを使わずに完全に作り直します

docker compose build --no-cache
docker compose up
docker compose exec web rails db:create

成功!!!!!!

docker compose up

エラー発生
LoadError: Error loading the 'postgresql' Active Record adapter.
pg is not part of the bundle. Add it to your Gemfile. (LoadError)

また別のエラーでた、、、、

postgresql の Active Record アダプタを読み込む際にエラーが発生しました。
pg は bundle(インストールされたgem群)に含まれていません。
Gemfile に pg を追加してください。

Gemfileに追加:

ruby '3.4.5'
gem 'rails', '~> 8.0.2'
gem 'pg', '~> 1.4'   #追加
gem 'bootsnap', require: false

Gemfileを修正したので再度ビルドを実施します

docker compose up --build

エラー発生
LoadError: Error loading the 'postgresql' Active Record adapter.
Missing a gem it depends on? pg is not part of the bundle.
Add it to your Gemfile. (LoadError)

また同じエラーでた、、、

Gemfileには記載しているので、変更を反映させるために下記の手順を実施します

コンテナ完全停止+削除します

docker compose down --volumes --remove-orphans

Gemfile変更を反映させるためにイメージをビルドし直します

docker compose up --build

エラー発生
Could not find a server gem. Maybe you need to add one to the Gemfile?
gem "puma"

server 用の gem が見つかりません。Gemfile にgem "puma"を追加する必要があるかもしれません。

source 'https://rubygems.org'

ruby '3.4.5'
gem 'rails', '~> 8.0.2'
gem 'pg', '~> 1.4'
gem 'puma', '~> 6.0' #追加
gem 'bootsnap', require: false

Gemfile変更を反映させるためにイメージをビルドし直します

docker compose up --build

成功!!!!!!

ブラウザにてlocalhost:3000で検索します

エラー発生

migrate.png

migrateできていません。

docker compose exec web rails db:migrate

マイグレーションファイルに従ってテーブルなどを構築します

ブラウザにてlocalhost:3000で検索して確認をします

エラー発生

Importmap.png

未定義のローカル変数またはメソッド javascript_importmap_tags が、このオブジェクトには存在しません。

importmap-rails gemGemfileにない場合に起こるそうです

Gemfile に以下を追加:

source 'https://rubygems.org'

ruby '3.4.5'
gem 'rails', '~> 8.0.2'
gem 'pg', '~> 1.4'
gem 'puma', '~> 6.0'
gem 'importmap-rails'  #追加
gem 'bootsnap', require: false
docker compose build

Importmapをコンテナ内にインストールします

docker compose run web rails importmap:install
docker compose up

無事にブラウザに表示することができました!!!


最終構成 & 手順まとめ

  1. DockerとDocker Composeのインストール確認
  2. RailsアプリをGitHubからクローン
  3. 必要なファイルを作成
  4. Dockerfile の編集
  5. Gemfile の編集
  6. config/database.yml の修正
  7. コンテナをビルド&起動
  8. DB作成とマイグレーション
  9. Importmap をインストールする
  10. ブラウザでアプリ起動を確認

1. DockerとDocker Composeのインストール確認

docker -v
docker compose version

2. RailsアプリをGitHubからクローン

git clone https://github.com/<githubユーザー名>/<対象リンク> rails_docker
cd rails_docker
git checkout -b docker

3. 必要なファイルを作成

touch Dockerfile Gemfile Gemfile.lock docker-compose.yml

4.Dockerfile の編集

FROM ruby:3.4.5
RUN apt-get update -qq && apt-get install -y \
  nodejs \
  postgresql-client \
  yarn
WORKDIR /rails_docker
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .

5.Gemfile の編集

source 'https://rubygems.org'

ruby '3.4.5'
gem 'rails', '~> 8.0.2'
gem 'pg', '~> 1.4'
gem 'puma', '~> 6.0'
gem 'importmap-rails'
gem 'bootsnap', require: false

Gemfile.lock は空ファイルでOK。

6.Docker-compose.ymal の編集

version: '3'
services:
  db:
    image: postgres:12
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password

  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
    environment:
      RAILS_ENV: development 

7.config/database.yml の修正

 default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password
  pool: 5

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

8. コンテナをビルド&起動

docker compose up --build

9.config.assets設定を削除

grep -rn "config.assets" config/
config/environments/production.rb:28:config.assets.css_compressor = :sass
config/environments/production.rb:31:config.assets.compile = false
config/environments/development.rb:60:config.assets.quiet = true
config/initializers/assets.rb:4:Rails.application.config.assets.version = "1.0"
config/initializers/assets.rb:7:Rails.application.config.assets.paths << Emoji.images_path
config/initializers/assets.rb:12:Rails.application.config.assets.precompile += %w( admin.js admin.css )

それぞれのファイルを開いて上記の項目をコメントアウト

code config/environments/production.rb config/environments/development.rb config/initializers/assets.rb
# config.assets.css_compressor = :sass
# config.assets.compile = false
# config.assets.quiet = true
# Rails.application.config.assets.version = "1.0"
# Rails.application.config.assets.paths << Emoji.images_path
# Rails.application.config.assets.precompile += %w( admin.js admin.css )

10.DB作成とマイグレーション

docker compose exec web rails db:create
docker compose exec web rails db:migrate

11.Importmap をインストールする

docker compose exec web rails importmap:install

12. ブラウザでアプリ起動を確認

http://localhost:3000 にアクセスして、Railsアプリが起動していれば成功。

参考文献

2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?