第1章: Docker & Docker-Compose 超入門
🎯 この章で学ぶこと(所要時間: 4時間)
Dockerの基本概念を理解し、Rails開発環境をコンテナ化する方法を学びます。
📢 はじめに
こんにちは!第1章へようこそ。
多くの開発者が最初につまずくのが「環境構築」です。「自分のPCでは動くのに、他の人のPCでは動かない」という経験はありませんか?この章では、そんな悩みを解決するDockerという技術を学びます。
Dockerは最初は難しく感じるかもしれませんが、一度理解すれば開発効率が劇的に向上します。料理に例えると、毎回材料を買いに行って一から作るのではなく、「完璧なレシピと材料がセットになったミールキット」を使うようなものです。
🎓 この章を終えると...
- なぜDockerが必要なのか、その価値を理解できる
- Dockerの基本的な仕組みがわかる
- 実際にDockerを使ってRails環境を構築できる
- チーム開発で「環境の違い」に悩まなくなる
📚 学習の流れ
- セクション1: Dockerの概念を理解する(読むだけでOK)
- セクション2: Dockerをインストールして動作確認(実際にインストール)
- セクション3〜5: Dockerの詳細な概念を理解する(読むだけでOK)
- セクション6以降: 実際に手を動かしてRailsプロジェクトを作成
この章を進める前に、Docker Desktopをインストールする必要があります。 セクション2で詳しい手順を説明します。
それでは、開発現場で必須となっているDockerの世界へ一緒に飛び込みましょう!
1. Dockerとは何か?
🎯 身近な例で理解するDocker
Dockerを理解するために、まず身近な例から考えてみましょう。
🍱 お弁当箱の例え
-
従来の開発環境: 自宅のキッチンで料理を作る
- 人によって調味料が違う
- コンロの火力が違う
- 使える調理器具が違う
- → 同じレシピでも違う味になってしまう
-
Docker環境: 完全に同じお弁当箱セット
- 調味料も計量済み
- 調理器具も全て同じ
- 手順書も同梱
- → 誰が作っても同じ味になる!
🤔 なぜDockerが必要なのか?
実際の開発現場でよく起こる問題を見てみましょう:
シナリオ1: 新メンバーが参加
新メンバー: 「READMEの通りにセットアップしたのに動きません...」
先輩: 「あー、それRubyのバージョンが違うからかな。rbenvで3.4系を...」
新メンバー: 「MySQLも入れないとダメですか?」
先輩: 「そうそう、あとNode.jsも必要で、バージョンは...」
→ 環境構築だけで1日が終わる 😭
シナリオ2: 本番環境へのデプロイ
開発者: 「ローカルでは完璧に動いてたのに!」
運用: 「本番サーバーのOSバージョンが違うからかも...」
開発者: 「えっ、開発環境と同じにできないの?」
→ 「私のマシンでは動くのに...」問題 😱
💡 Dockerが解決すること
従来の開発での問題点:
- 開発環境と本番環境の差異
- チームメンバー間での環境の違い
- 依存関係の管理の複雑さ
- 環境構築に時間がかかる
- 「○○のバージョンが違う」問題
Dockerが解決すること:
- 環境の一貫性: どこでも同じ環境で動作
- 簡単な環境構築:
docker compose up一発で全員同じ環境 - 依存関係の隔離: プロジェクトごとに独立した環境
- バージョン管理: 環境自体もコードとして管理
- クリーンな環境: プロジェクトを消せば環境も完全に削除
📦 コンテナとは?
コンテナは、アプリケーションとその実行に必要なすべてをパッケージ化したものです。
🏠 アパートの例えで理解する
-
仮想マシン: 一戸建て住宅
- 土地から基礎、水道、電気、すべて独立
- 豪華だけど重い、起動も遅い
- リソース(土地)をたくさん使う
-
コンテナ: アパートの一室
- 基礎インフラ(水道、電気)は共有
- 必要な部分だけ独立(部屋の中)
- 軽くて、すぐ入居(起動)できる
- 効率的にリソースを使える
🆚 仮想マシン vs コンテナの詳細比較
📊 リソース使用量の違い
🎯 どちらを使うべき?
| 項目 | 仮想マシン | コンテナ |
|---|---|---|
| 使用場面 | 異なるOSが必要 完全な隔離が必要 | 同じOSで動作 開発環境の統一 |
| 起動時間 | 🐌 数分 | ⚡ 数秒 |
| リソース | 🏋️ 重い(GB単位) | 🪶 軽い(MB単位) |
| 隔離レベル | 🔒 完全隔離 | 🔗 プロセス隔離 |
| 適した用途 | Windows上でLinux 本番環境の完全再現 | 開発環境 マイクロサービス |
🚀 Dockerの動作イメージ
実際にDockerがどのように動くのか、簡単な流れを見てみましょう:
2. Dockerのインストール
📦 Docker Desktopのインストール
Dockerを使うためには、まずDocker Desktopをインストールする必要があります。
🔗 公式インストールガイド:
- 上記のリンクから、お使いのOSに合ったインストーラーをダウンロード
- ダウンロードしたファイルを実行し、指示に従ってインストール
- インストール後、Docker Desktopを起動
- ターミナルを開いて、以下のコマンドで動作確認
✅ インストールの確認
🔨 実際にやってみましょう! Dockerが正しくインストールされたか確認します:
# Dockerのバージョンを確認
docker --version
# Docker Composeのバージョンを確認
docker compose version
📄 期待される出力例:
Docker version 24.0.7, build afdd53b
Docker Compose version v2.23.3
バージョン番号は異なっていても問題ありません。 重要なのは、両方のコマンドが正常に動作することです。
🚀 最初のコンテナを実行
🔨 実際にやってみましょう! 以下のコマンドを順番に実行してください:
# Dockerが正しくインストールされているか確認
docker --version
# Hello Worldコンテナを実行
docker run hello-world
上記のコマンドをコピーして、ターミナルに貼り付けて実行してください。
#で始まる行はコメントなので、実行されません。
📋 期待される出力例:
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
🔍 何が起きたのか?
このシンプルな例から、Dockerの基本的な動作がわかります:
- イメージ: アプリケーションのテンプレート(設計図)
- コンテナ: イメージから作られた実行環境(実際の部屋)
- Docker Hub: イメージを共有する場所(図書館のような場所)
3. Rails用Dockerfileの理解
以下のコードは理解のための参考例です。実際の作成は第6章で行います。
📝 Dockerfileとは?
Dockerfileは、Dockerイメージを作成するための設計図です。
Rails開発用のDockerfileは以下のような構成になります:
# ベースイメージの指定
FROM ruby:3.4
# 必要なパッケージのインストール
RUN apt-get update -qq && apt-get install -y \
nodejs \
default-mysql-client \
npm \
vim
# Node.jsの最新版をインストール(Rails 8のため)
RUN npm install -g yarn
# 作業ディレクトリの設定
WORKDIR /app
# GemfileとGemfile.lockをコピー
COPY Gemfile* ./
# Gemのインストール
RUN bundle install
# アプリケーションのコードをコピー
COPY . .
# ポート3000を公開
EXPOSE 3000
# サーバー起動コマンド
CMD ["rails", "server", "-b", "0.0.0.0"]
📚 Dockerfileの詳細解説
1. ベースイメージの選択
FROM ruby:3.4
- FROM: すべてのDockerfileは
FROM命令から始まります - ruby:3.4: Docker Hub公式のRubyイメージ(バージョン3.4)を使用
- このイメージには、Ruby実行環境と基本的なツールが含まれています
- サイズと機能のバランスが良い選択です
2. システムパッケージのインストール
RUN apt-get update -qq && apt-get install -y \
nodejs \
default-mysql-client \
vim
- RUN: コンテナ内でコマンドを実行し、結果を新しいレイヤーとして保存
- apt-get update -qq: パッケージリストを静かに(-qq)更新
- apt-get install -y: 確認なし(-y)でパッケージをインストール
- nodejs: JavaScriptランタイム(Rails Asset Pipeline用)
- default-mysql-client: MySQLクライアントツール(
rails dbコマンド用) - vim: テキストエディタ(デバッグ時に便利)
3. 作業ディレクトリの設定
WORKDIR /app
- WORKDIR: 以降のコマンドの実行ディレクトリを設定
/appディレクトリが存在しない場合は自動的に作成されます- コンテナ内でのファイル配置を整理できます
4. 依存関係の効率的なインストール
COPY Gemfile* ./
RUN bundle install
- *COPY Gemfile ./**: GemfileとGemfile.lockのみを先にコピー
- なぜ分けるのか?:
- Dockerはレイヤーキャッシュシステムを使用
- Gemfileが変更されない限り、
bundle installの結果がキャッシュされる - これにより、コード変更時のビルド時間が大幅に短縮されます
5. アプリケーションコードのコピー
COPY . .
- COPY . .: 現在のディレクトリ(ホスト)の内容を作業ディレクトリ(コンテナ)にコピー
- Docker無視設定ファイルで除外されたファイルはコピーされません
- 依存関係のインストール後に実行することで、キャッシュを最大限活用
6. ポートの公開
EXPOSE 3000
- EXPOSE: コンテナがリッスンするポートを文書化
- 実際のポート公開は
docker run -pやdocker-compose.ymlで行います - 他の開発者にどのポートを使用するか伝える役割もあります
7. デフォルトコマンドの設定
CMD ["rails", "server", "-b", "0.0.0.0"]
- CMD: コンテナ起動時のデフォルトコマンド
- 配列形式(exec形式)で記述することでシェルを介さずに実行
-b 0.0.0.0: すべてのネットワークインターフェースでリッスン(コンテナ外からアクセス可能に)
🎯 ベストプラクティス(初心者向け詳細解説)
1. レイヤーの最適化 - なぜ順番が大切なのか?
Dockerは各命令を「レイヤー」として保存します。以下の例で理解しましょう:
# ❌ 悪い例:コードを先にコピー
COPY . . # レイヤー1:全ファイルコピー
RUN bundle install # レイヤー2:Gem インストール
# ✅ 良い例:依存関係を先に処理
COPY Gemfile* ./ # レイヤー1:Gemfileのみコピー
RUN bundle install # レイヤー2:Gem インストール
COPY . . # レイヤー3:残りのファイルコピー
なぜ良い例の方が優れているのか?
- コードを1行変更しただけの場合:
- 悪い例:レイヤー1から再ビルド →
bundle installも再実行(5分かかる) - 良い例:レイヤー3だけ再ビルド →
bundle installはキャッシュ使用(数秒)
- 悪い例:レイヤー1から再ビルド →
2. キャッシュの活用 - ビルド時間を10分から30秒に短縮
Dockerのキャッシュシステムを理解して活用しましょう:
# Dockerfileの各行は上から順に実行され、
# 変更があった行から下はすべて再実行される
FROM ruby:3.4 # ほぼ変更なし → キャッシュ使用
RUN apt-get update && apt-get... # ほぼ変更なし → キャッシュ使用
WORKDIR /app # 変更なし → キャッシュ使用
COPY Gemfile* ./ # Gemfile変更時のみ再実行
RUN bundle install # ↑が変更された時のみ再実行
COPY . . # コード変更時は常に再実行
実践的なヒント:
Gemfileを変更 → 約3-5分の再ビルド- Rubyコードだけ変更 → 約10-30秒の再ビルド
3. RUNコマンドの結合 - イメージサイズを削減
# ❌ 悪い例:複数のRUNコマンド(各コマンドが新しいレイヤーを作成)
RUN apt-get update
RUN apt-get install -y nodejs
RUN apt-get install -y default-mysql-client
RUN apt-get clean
# → 4つのレイヤー、中間ファイルも保存される
# ✅ 良い例:1つのRUNコマンドに結合
RUN apt-get update && \
apt-get install -y \
nodejs \
default-mysql-client && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# → 1つのレイヤー、クリーンアップも同じレイヤー内で完了
メリット:
- イメージサイズが小さくなる(500MB → 300MB など)
- ダウンロード時間が短縮される
4. セキュリティ - 本番環境での注意点
# 開発環境(現在使用中)
FROM ruby:3.4
# → 便利だが、サイズが大きい(約800MB)
# 本番環境の選択肢
FROM ruby:3.4-alpine
# → 軽量(約50MB)だが、設定が少し複雑
FROM ruby:3.4-slim
# → 中間的な選択(約150MB)
初心者へのアドバイス:
- まずは通常のイメージ(
ruby:3.4)で動作確認 - 慣れてきたら軽量イメージに挑戦
- 不要なツール(vim等)は本番環境では削除
5. Docker無視設定ファイルの活用 - 不要なファイルを除外
プロジェクトルートにDocker無視設定ファイル(.dockerignore)を配置することで、不要なファイルをDockerイメージから除外できます:
# Docker無視設定
.git
.gitignore
README.md
.env
.env.*
tmp/
log/
.DS_Store
node_modules/
coverage/
.rspec_status
効果:
- ビルド時間の短縮(不要なファイルをコピーしない)
- イメージサイズの削減
- セキュリティの向上(秘密情報を含まない)
🔨 イメージのビルド
Dockerfileが準備できたら、以下のコマンドでイメージをビルドします:
# Dockerイメージをビルド
docker build -t todo-api .
# ビルドされたイメージを確認
docker images
ビルドプロセスの流れ:
- ベースイメージ(ruby:3.4)をダウンロード
- 必要なパッケージをインストール
- アプリケーションファイルをコピー
- 依存関係(Gem)をインストール
- 最終的なイメージを作成
📂 ホストとコンテナのファイルシステム関係
DockerのCOPYコマンドとWORKDIRの関係を理解するため、以下の図で確認しましょう:
📊 ビルドプロセスの流れ
📁 ファイルシステムの対応関係
🔑 重要なポイント
-
WORKDIR /app
- コンテナ内に
/appディレクトリを作成し、作業ディレクトリに設定 - 以降のコマンドはすべてこのディレクトリで実行される
- コンテナ内に
-
COPY Gemfile ./*
- ホストの
GemfileとGemfile.lockを - コンテナの現在のディレクトリ(
/app)にコピー ./は/app/を意味する
- ホストの
-
COPY . .
- ホストの現在のディレクトリ(プロジェクトルート)のすべてのファイルを
- コンテナの現在のディレクトリ(
/app)にコピー - 最初の
.はホスト側、2番目の.はコンテナ側を指す
-
ボリュームマウント(docker-compose.yml)
volumes:
- .:/app # ホストの現在のディレクトリをコンテナの/appにマウント- 開発時はCOPYではなくボリュームマウントを使用
- ホストのファイル変更が即座にコンテナに反映される
4. Docker Composeで複数コンテナ管理
以下のコードは理解のための参考例です。実際の作成は第6章で行います。
📋 docker-compose.ymlの構成
Docker Composeを使用すると、複数のコンテナを一つの設定ファイルで管理できます。Rails開発では、以下のようなdocker-compose.ymlを使用します:
version: '3.9'
services:
db:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: todo_development
MYSQL_USER: todoapp
MYSQL_PASSWORD: password
ports:
- "3306:3306"
command: --default-authentication-plugin=mysql_native_password
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails server -b 0.0.0.0"
volumes:
- .:/app
ports:
- "3000:3000"
depends_on:
- db
environment:
DATABASE_HOST: db
DATABASE_USER: todoapp
DATABASE_PASSWORD: password
stdin_open: true
tty: true
volumes:
mysql_data:
🎯 各設定の詳細解説
📦 まず理解すること:2つのコンテナ
docker-compose.ymlでは、2つの独立したコンテナを定義しています:
dbコンテナ - MySQLデータベースが動く箱webコンテナ - Railsアプリケーションが動く箱
services:
db: # データベース用のコンテナ
...
web: # Railsアプリ用のコンテナ
...
これらのコンテナは、それぞれ独立した小さなコンピュータのようなものです。
🔑 重要な概念:サービス名
services:
db: # ← この名前が重要!
image: mysql:8.0
web: # ← この名前も重要!
build: .
ポイント:
dbという名前は、他のコンテナからデータベースにアクセスする時の「住所」になりますwebという名前も同様に、このコンテナの「住所」になります
🌐 コンテナ同士の通信
web:
environment:
DATABASE_HOST: db # "db"コンテナに接続
なぜ DATABASE_HOST: db なのか?
- Docker Composeが自動的に内部ネットワークを作成
- コンテナ同士はサービス名で通信できる
localhostではなくdbを使うのがポイント!
📊 全体像:コンテナとネットワーク
🔌 ポートマッピング:外部からコンテナへのアクセス
ここまでで、コンテナ同士は内部ネットワークで通信できることが分かりました。 では、あなたのPCからコンテナにアクセスするにはどうすればよいでしょうか?
この問題を解決するのがポートマッピングという仕組みです。
🔧 各設定項目の詳細解説
1. ポートマッピングの仕組み
ports:
- "3306:3306" # "ホスト側:コンテナ側"
- 左側(3306): あなたのPCの3306番ポート
- 右側(3306): コンテナ内の3306番ポート
- つまり、
localhost:3306にアクセスすると、コンテナ内のMySQLに繋がる
例えて言うと:
- コンテナは「部屋」
- ポートは「ドア」
- ポートマッピングは「外のドア」と「部屋のドア」を繋ぐ通路
2. データベースの設定(dbコンテナ)
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: todo_development
MYSQL_USER: todoapp
MYSQL_PASSWORD: password
各環境変数の役割:
MYSQL_ROOT_PASSWORD: 管理者パスワードMYSQL_DATABASE: 自動作成されるデータベース名MYSQL_USER: アプリケーション用のユーザーMYSQL_PASSWORD: そのユーザーのパスワード
3. Railsアプリの設定(webコンテナ)
web:
build: .
environment:
DATABASE_HOST: db # "db"コンテナに接続
DATABASE_USER: todoapp
DATABASE_PASSWORD: password
ポイント:
DATABASE_HOST: dbで、データベースコンテナを指定- ユーザー名とパスワードは
dbコンテナで設定したものと同じ
4. 起動順序の制御
depends_on:
- db # dbコンテナが起動してからwebコンテナを起動
- データベースが準備できてからRailsを起動する
- 起動順序のトラブルを防ぐ
5. ボリュームマウントの使い分け
volumes:
- .:/app # バインドマウント(開発用)
- mysql_data:/var/lib/mysql # 名前付きボリューム(永続化)
- バインドマウント: ファイル変更が即座に反映
- 名前付きボリューム: データベースのデータを保持
💡 初心者がつまずきやすいポイント
1. なぜlocalhostではダメなのか?
# ❌ 間違い:webコンテナ内でlocalhostを使う
DATABASE_HOST: localhost
# ✅ 正解:サービス名を使う
DATABASE_HOST: db
理由:
- 各コンテナは独立した環境
- webコンテナ内の
localhostは、webコンテナ自身を指す - dbコンテナにアクセスするには、サービス名
dbを使う必要がある
2. ポートの重複に注意
もし既に3306番ポートが使われている場合:
ports:
- "3307:3306" # ホスト側を3307に変更
3. データの永続化を忘れずに
volumes:
mysql_data: # この設定がないとコンテナ削除時にデータが消える!
📝 まとめ:docker-compose.ymlの全体像
- services: 複数のコンテナを定義
- サービス名: コンテナ同士の通信に使用
- ports: 外部からコンテナへのアクセス経路
- environment: コンテナ内で使う設定値
- depends_on: 起動順序の制御
- volumes: データの永続化とファイル共有
5. ボリュームとバインドマウント
💾 ボリュームとは?
Dockerコンテナは本来「使い捨て」の環境です。コンテナを削除すると、その中のデータも一緒に消えてしまいます。 しかし、開発では以下のようなデータを保持したいケースがあります:
- データベースのデータ - ユーザー情報やアプリケーションデータ
- ソースコード - 編集中のプログラムファイル
- 設定ファイル - 環境固有の設定
そこで使うのがボリュームです。
📦 ボリュームの種類と特徴
1. 名前付きボリューム(Named Volume)
volumes:
mysql_data:/var/lib/mysql
特徴:
- Dockerが管理する特別な保存領域
- コンテナを削除してもデータは残る
- 複数のコンテナで共有可能
- ホストマシンのどこに保存されているかは意識しない
使用例:
services:
db:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql # データベースの永続化
動作イメージ:
2. バインドマウント(Bind Mount)
volumes:
- .:/app # ホストの現在のディレクトリをコンテナの/appにマウント
特徴:
- ホストマシンの特定のディレクトリをコンテナ内にマウント
- ファイルの変更が即座に反映される(リアルタイム同期)
- 開発時のソースコード共有に最適
- ホスト側のパスを明示的に指定
使用例:
services:
web:
build: .
volumes:
- .:/app # 開発中のコードを即座に反映
動作イメージ:
🎯 実際の使い分け例
services:
db:
image: mysql:8.0
volumes:
# データベースのデータは名前付きボリューム
- mysql_data:/var/lib/mysql
# カスタム設定ファイルはバインドマウント
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf:ro
web:
build: .
volumes:
# ソースコードはバインドマウント(開発用)
- .:/app
volumes:
mysql_data: # 名前付きボリュームの宣言
💡 ボリュームの管理コマンド
# ボリューム一覧を表示
docker volume ls
# ボリュームの詳細情報
docker volume inspect mysql_data
# 不要なボリュームを削除
docker volume prune
# 特定のボリュームを削除
docker volume rm mysql_data
🤝 使い分けの指針
| 種類 | 用途 | 例 | 理由 |
|---|---|---|---|
| 名前付きボリューム | データベース | mysql_data:/var/lib/mysql | データの永続化が必要 |
| バインドマウント | ソースコード | .:/app | リアルタイム編集が必要 |
| バインドマウント | 設定ファイル | ./nginx.conf:/etc/nginx/nginx.conf | ホスト側で管理したい |
⚠️ 注意点
-
パフォーマンス
- Windowsでバインドマウントを使うと遅い場合がある
- その場合は、WSL2の使用を検討
-
権限問題
- Linuxではファイルの所有者に注意
- 必要に応じて
userオプションを使用
-
読み取り専用オプション
volumes:
- ./config.yml:/app/config.yml:ro # 読み取り専用
6. 実践: Rails APIプロジェクトの作成
ここまでは概念の説明でした。ここからは実際に手を動かしてプロジェクトを作成していきます。 ターミナルを開いて、一緒に進めていきましょう!
🛠 プロジェクトディレクトリの作成
🔨 実際にやってみましょう! まずはプロジェクトディレクトリを作成します:
# プロジェクト用の親ディレクトリを作成(まだない場合)
mkdir -p ~/projects
# プロジェクトディレクトリを作成して移動
cd ~/projects
mkdir todo-api
cd todo-api
# 現在のディレクトリを確認
pwd
# 期待される出力例:
# /Users/yourname/projects/todo-api
# または
# /home/yourname/projects/todo-api
~/projects はホームディレクトリ下の projects フォルダを意味します。
お好みで以下のような場所でも構いません:
~/workspace/todo-api~/dev/todo-api~/Documents/projects/todo-api
重要なのは、後で見つけやすい場所に作成することです。
📚 前提条件:Ruby/Railsのインストール
開発環境の一貫性を保つため、ホストマシンにもRuby/Railsをインストールしておきましょう。
このチュートリアルでは、以下のバージョンを使用します:
- Ruby 3.4.x(3.4.0以上)
- Rails 8.0.x(8.0.2以上)
バージョン確認コマンドの実行例:
$ ruby -v
ruby 3.4.0 (2024-12-25 revision 48d4efcb85) +PRISM [arm64-darwin23]
# 3.4.1や3.4.4など、3.4系であればOK
$ rails -v
Rails 8.0.2
- Rubyのパッチバージョン(3.4.0→3.4.4など)の違いは通常問題ありません
- Dockerを使用することで、チーム全体で同じ環境を共有できます
:::
- Dockerコンテナの起動を待たずに素早くコマンドを実行できる
- エディタの補完機能が正しく動作する
- デバッグが容易になる
🔨 Ruby/Railsのインストール方法
Ruby/Railsのインストールには複数の方法があります:
-
Rails Girls インストールガイド(初心者向け)
- Rails Girls インストールガイド では、OS別(Mac/Windows/Linux)の詳しいインストール手順が日本語で解説されています
- 初めてRubyをインストールする方におすすめです
-
rbenvを使った方法(推奨)
- より柔軟なバージョン管理が可能
- プロジェクトごとに異なるRubyバージョンを使い分けられる
- 本教材ではこちらの方法を詳しく説明します
📝 rbenvを使ったインストール手順
1. Homebrewのインストール確認
# Homebrewがインストールされているか確認
which brew
which brew で何も表示されない場合は、先に Homebrew のセットアップガイド を参照してHomebrewをインストールしてください。
特にApple Silicon Mac(M1/M2/M3)をお使いの方は、パスの設定が必要です。
2. rbenvのインストール
🔨 実際にやってみましょう!
# rbenvとruby-buildをインストール
brew install rbenv ruby-build
# rbenvの設定を.zshrcに追加
echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc
# 設定を反映
source ~/.zshrc
# rbenvが正しくインストールされたか確認
rbenv -v
# 期待される出力例: rbenv 1.3.0
macOSのデフォルトシェルはzshですが、bashを使用している場合は:
echo 'eval "$(rbenv init - bash)"' >> ~/.bash_profile
source ~/.bash_profile
3. Rubyのインストール
🔨 実際にやってみましょう!
# インストール可能なRubyバージョンを確認
rbenv install -l | grep -E "^3\.4\.[0-9]+$"
# Ruby 3.4系の最新版をインストール(例: 3.4.4)
rbenv install 3.4.4
# グローバルで使用するRubyバージョンを設定
rbenv global 3.4.4
# Rubyのバージョンを確認
ruby -v
# 期待される出力例: ruby 3.4.4 (2024-...) [arm64-darwin23]
Rubyのインストールには5-10分程度かかることがあります。 コーヒーでも飲みながら待ちましょう ☕
4. bundlerのアップデート
# bundlerを最新版にアップデート
gem update bundler
# bundlerのバージョンを確認
bundler -v
# 期待される出力例: Bundler version 2.5.22
5. Railsのインストール
🔨 実際にやってみましょう!
# Rails 8をインストール
gem install rails -v "~> 8.0.0"
# Railsのバージョンを確認
rails -v
rails -v を実行して以下のようなエラーが出る場合があります:
Rails is not currently installed on this system. To get the latest version, simply type:
$ sudo gem install rails
You can then rerun your "rails" command.
解決方法:
# rbenvのrehashを実行
rbenv rehash
# 再度Railsのバージョンを確認
rails -v
# 期待される出力: Rails 8.0.2
なぜこのエラーが起きるのか?
- rbenvは新しくインストールしたGemのコマンドを認識するために
rehashが必要です - 通常は自動的に実行されますが、タイミングによっては手動実行が必要な場合があります
rbenv rehashは、インストールされたGemの実行ファイルへのシムリンクを更新します
6. プロジェクトごとのRubyバージョン管理
# プロジェクトディレクトリに移動
cd todo-api
# このプロジェクトで使用するRubyバージョンを指定
rbenv local 3.4.4
# .ruby-versionファイルが作成されたことを確認
cat .ruby-version
# 出力: 3.4.4
rbenv versions: インストール済みのRubyバージョン一覧rbenv install -l: インストール可能なバージョン一覧rbenv local: プロジェクト固有のバージョン設定rbenv global: システム全体のデフォルトバージョン設定
🚀 Railsプロジェクトの作成
⚠️ 重要:プロジェクトディレクトリの確認
まず、正しいディレクトリにいることを確認しましょう:
# 現在のディレクトリを確認
pwd
# もし todo-api ディレクトリにいない場合は移動
# (最初に作成したプロジェクトディレクトリです)
cd ~/projects/todo-api # ご自身が作成したパスに置き換えてください
ホームディレクトリなど、間違った場所で rails new . を実行すると、そのディレクトリ全体がRailsプロジェクトになってしまい、既存のファイルが上書きされる可能性があります!
必ず空の todo-api ディレクトリ内で実行してください。
🔨 実際にやってみましょう! プロジェクトディレクトリ内でRailsプロジェクトを作成します:
# Railsがインストールされているか確認
rails --version
# Rails APIプロジェクトを作成(現在のディレクトリに作成)
rails new . --api -d mysql -T --skip-bundle
📚 コマンドの解説:
rails new .: 現在のディレクトリにRailsアプリを作成--api: API専用モード(ViewやAsset Pipelineを除外)-d mysql: データベースにMySQLを使用(デフォルトはSQLite)-T: デフォルトのテストフレームワーク(Minitest)をスキップ--skip-bundle: この時点ではbundle installを実行しない(後で必要なGemを追加してから実行)
このコマンドでRailsの基本的なファイル構造が作成され、GemfileやGit無視設定ファイルも自動生成されます。
📝 無視設定ファイルの確認
Rails 8では、以下のようなGit無視設定ファイル(.gitignore)が自動生成されます。必要に応じてこの内容をコピペしてください:
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# Temporary files generated by your text editor or operating system
# belong in git's global ignore instead:
# `$XDG_CONFIG_HOME/git/ignore` or `~/.config/git/ignore`
# Ignore bundler config.
/.bundle
# Ignore all environment files.
/.env*
# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep
# Ignore pidfiles, but keep the directory.
/tmp/pids/*
!/tmp/pids/
!/tmp/pids/.keep
# Ignore storage (uploaded files in development and any SQLite databases).
/storage/*
!/storage/.keep
/tmp/storage/*
!/tmp/storage/
!/tmp/storage/.keep
# Ignore master key for decrypting credentials and more.
/config/master.key
/.env*で環境変数ファイルが自動的に無視されます/log/*や/tmp/*で一時ファイルが無視されます!/log/.keepのような記述で、ディレクトリ構造は保持されます- 通常、このデフォルト設定のままで問題ありません
📝 Gemfileの編集
🔨 実際にやってみましょう! 環境変数を管理するためのGemを追加します。Gemfileを開いて以下を追加してください:
group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem "debug", platforms: %i[ mri windows ]
# 環境変数を.envファイルから読み込む
gem "dotenv-rails"
end
📦 依存関係のインストール
🔨 実際にやってみましょう! Gemfileを編集したので、bundle installを実行してGemfile.lockを生成します:
# 依存関係をインストールし、Gemfile.lockを生成
bundle install
macOSでよく発生するmysql2関連のエラーメッセージ例:
ld: library 'zstd' not foundld: library not found for -lsslmysql client is missing
これらのエラーが発生した場合は、mysql2 gem インストール トラブルシューティングを参照してください。
よくある解決方法(zstdエラーの場合):
# zstdライブラリのパスを設定してから再実行
export LIBRARY_PATH=$LIBRARY_PATH:$(brew --prefix zstd)/lib/
bundle install
Gemfile.lockは、チーム全員が同じバージョンのGemを使うために必要なファイルです。
Dockerビルド時にもこのファイルが必要になります。
🔑 Rails credentialsファイルの削除
🔍 確認してみましょう! Rails 8ではrails new実行時に認証情報関連のファイルが自動生成されることがあります:
# credentialsファイルが存在するか確認
ls -la config/master.key config/credentials.yml.enc 2>/dev/null || echo "ファイルは存在しません"
もしこれらのファイルが存在する場合は、本教材では環境変数による管理を採用するため削除します:
# Rails credentialsファイルを削除
rm -f config/master.key config/credentials.yml.enc
本教材では第3章で詳しく説明しますが、以下の理由から環境変数での管理を採用しています:
- シンプルさ: 初学者にとって環境変数の方が理解しやすい
- Docker環境との相性: コンテナ環境では環境変数の管理が容易
- 汎用性: 多くのPaaSで標準的な方法
Rails Tutorialではrails credentials:editを使った管理方法が紹介されていますが、本教材ではより現代的で汎用的な環境変数による管理を学びます。
📝 Docker無視設定ファイルの確認と更新
🔍 まずは確認してみましょう! Rails 8ではDocker無視設定ファイルが自動生成されることがあります:
# Docker無視設定ファイルが存在するか確認
ls -la .dockerignore
rails new --apiを実行した際、Rails 8では基本的なDocker無視設定ファイルが自動生成されることがあります。
もし存在しない場合は、以下のコマンドで作成してください:
touch .dockerignore
📝 Docker無視設定ファイルの内容を確認・更新します。以下の内容が含まれていることを確認し、必要に応じて追加してください:
# Git関連
.git
.gitignore
README.md
# 環境変数
.env
.env.*
!.env.example
# ログと一時ファイル
tmp/
log/
# OS関連
.DS_Store
# Node.js関連(後でReactを追加する場合)
node_modules/
# テストカバレッジ
coverage/
.rspec_status
# エディタ設定
.vscode/
.idea/
- Dockerイメージのサイズを削減
- ビルド時間の短縮
- セキュリティの向上(秘密情報を含まない)
📝 Dockerfileの確認と更新
🔍 まずは確認してみましょう! Rails 8ではDockerfileが自動生成されます:
# Dockerfileが存在するか確認
ls -la Dockerfile
rails new --apiを実行した際、Rails 8では本番用に最適化されたDockerfileが自動生成されます。
しかし、開発環境ではよりシンプルな設定が適しているため、内容を書き換えます。
📝 Dockerfileを以下の内容で完全に置き換えてください:
# ベースイメージの指定
FROM ruby:3.4
# 必要なパッケージのインストール
RUN apt-get update -qq && apt-get install -y \
nodejs \
default-mysql-client \
npm \
vim
# Node.jsの最新版をインストール(Rails 8のため)
RUN npm install -g yarn
# 作業ディレクトリの設定
WORKDIR /app
# GemfileとGemfile.lockをコピー
COPY Gemfile* ./
# Gemのインストール
RUN bundle install
# アプリケーションのコードをコピー
COPY . .
# ポート3000を公開
EXPOSE 3000
# サーバー起動コマンド
CMD ["rails", "server", "-b", "0.0.0.0"]
再三お伝えしているように、理解は後からついてきます。まずは動かしながら、Dockerの使い方に慣れていきましょう。
📝 docker-compose.ymlの作成
🔨 実際にやってみましょう! docker-compose.ymlを作成します:
# docker-compose.ymlを作成
touch docker-compose.yml
📝 作成したdocker-compose.ymlに以下の内容を記述してください:
version: '3.9'
services:
db:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
ports:
- "3306:3306"
command: --default-authentication-plugin=mysql_native_password
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails server -b 0.0.0.0"
volumes:
- .:/app
ports:
- "3000:3000"
depends_on:
- db
env_file:
- .env
stdin_open: true
tty: true
volumes:
mysql_data:
📝 環境変数ファイルの作成
🔨 実際にやってみましょう! 環境変数を管理する.envファイルを作成します:
# まず、サンプルファイルを作成
touch .env.example
📝 作成した.env.exampleに以下の内容を記述してください:
# データベース接続情報(Rails用)
DATABASE_HOST=db
DATABASE_USER=todoapp
DATABASE_PASSWORD=password
# MySQL設定(docker-compose用)
MYSQL_ROOT_PASSWORD=rootpassword
MYSQL_DATABASE=todo_development
MYSQL_USER=todoapp
MYSQL_PASSWORD=password
🔨 次に、実際の.envファイルを作成します:
# サンプルファイルをコピーして.envを作成
cp .env.example .env
.env.exampleを先に作成: チーム開発で必要な環境変数の「設計書」として機能- コピーして
.envを作成: サンプルをベースに、実際の値を設定できる
この方法により、新しいメンバーが参加した際も、.env.exampleを見れば必要な環境変数がすぐに分かります。
.envファイルには本番環境のパスワードなど重要な情報が含まれます- 絶対にGitにコミットしないよう注意してください(Git無視設定ファイルで無視されます)
.env.exampleには実際のパスワードではなく、例示的な値を入れておきましょう
📝 データベース設定の更新
🔨 実際にやってみましょう! config/database.ymlを環境変数を使用する形に更新します:
default: &default
adapter: mysql2
encoding: utf8mb4
host: <%= ENV['DATABASE_HOST'] %>
username: <%= ENV['DATABASE_USER'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: todo_development
test:
<<: *default
database: todo_test
production:
<<: *default
database: todo_production
📚 環境変数の解説:
<%= ENV['DATABASE_HOST'] %>: 環境変数DATABASE_HOSTの値を使用ENV.fetch("RAILS_MAX_THREADS") { 5 }: 環境変数が設定されていない場合は5を使用- dotenv-rails gemが
.envファイルを自動的に読み込んでくれます
- システムの環境変数
- docker-compose.ymlで設定した環境変数
- .envファイルの環境変数 上位の設定が優先されます。
🔨 Dockerイメージのビルド
ここまでで以下のファイルが作成されているはずです:
- Railsプロジェクトのファイル群(Gemfile、Gemfile.lock含む)
- Dockerfile
- docker-compose.yml
- Docker無視設定ファイル
- .env
- .env.example
🔨 実際にやってみましょう! Dockerイメージをビルドします:
以下のコマンドを実行する前に、Docker Desktopが起動していることを確認してください。
もし「Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?」というエラーが出た場合:
- Docker Desktopアプリケーションを起動
- システムトレイ(Mac: 右上、Windows: 右下)のDockerアイコンが正常に表示されるまで待つ
docker versionコマンドで接続確認
# Dockerイメージをビルド
docker compose build
- Gemfile.lockが存在するので、確実に同じバージョンのGemがインストールされます
- 初回は5-10分程度かかります
- 2回目以降はキャッシュが効くので速くなります
🎉 アプリケーションの起動
ここまでホストマシンでセットアップを行いました。ここからはDocker Composeを使って実際にアプリケーションを起動します。
- データベース(MySQL)との接続が簡単
- 本番環境に近い状態で開発できる
- チーム全員が同じ環境で開発できる
🔨 実際にやってみましょう! Docker Composeでアプリケーションを起動します:
ステップ1: コンテナを起動
# コンテナを起動
docker compose up
ログに以下のようなメッセージが表示されたら起動完了です:
web_1 | => Booting Puma
web_1 | => Rails 7.1.0 application starting in development
web_1 | => Run `bin/rails server --help` for more startup options
web_1 | Listening on http://0.0.0.0:3000
ステップ3: データベースを作成
🔨 別のターミナルを開いて、データベースを作成します:
# データベースを作成
docker compose exec web rails db:create
期待される出力:
Created database 'todo_development'
Created database 'todo_test'
ステップ4: ブラウザで確認
🌐 ブラウザで確認しましょう!
- ブラウザを開く
- アドレスバーに
http://localhost:3000を入力 - Railsのウェルカムページが表示されれば成功!🎉
Railsのデフォルトウェルカムページが表示されます。以下のような内容が含まれています:
- 中央に赤い円形のRailsロゴ
- Rails version: 8.0.2
- Ruby version: ruby 3.4.4
- Rack version: 3.1.16

このページが表示されれば、Rails APIアプリケーションが正常に起動しています!
docker compose psでコンテナの状態を確認docker compose logs webでエラーログを確認- ポート3000が既に使われていないか確認
7. よく使うDockerコマンド
🔧 基本コマンド
📚 以下は参考用のコマンド集です。必要に応じて使ってください:
# コンテナの起動
docker compose up
# バックグラウンドで起動
docker compose up -d
# コンテナの停止
docker compose down
# コンテナの再起動
docker compose restart web
# ログの確認
docker compose logs -f web
# コンテナ内でコマンド実行
docker compose exec web bash
docker compose exec web rails console
docker compose exec web rails db:migrate
# 一時的なコンテナでコマンド実行
docker compose run --rm web rails generate model User
🧹 クリーンアップ
⚠️ 以下のコマンドは注意して使用してください:
# 停止したコンテナを削除
docker compose rm
# ボリュームも含めて削除(データベースも消えます!)
docker compose down -v
# 不要なイメージを削除
docker image prune
# システム全体のクリーンアップ(全プロジェクトに影響!)
docker system prune -a
docker compose down -v を実行すると、データベースのデータも削除されます。
開発中のデータを残したい場合は -v オプションを付けないでください。
まとめ
この章で学んだことを確認しましょう。理解できた項目にチェックを入れてください:
このチェックリストは学習の振り返り用です。ブラウザ上でクリックしてもチェックは保存されませんが、自分の理解度を確認するために使ってください。
🐳 Dockerの基本概念
- Dockerとは何か、なぜ必要なのかを説明できる
- コンテナと仮想マシンの違いを理解している
-
docker run hello-worldコマンドで何が起きるか説明できる
📝 Dockerfileの作成と理解
- Dockerfileの基本的な命令(FROM, RUN, WORKDIR, COPY, CMD)を理解している
- ベースイメージの選び方がわかる
- レイヤーキャッシュの仕組みと最適化方法を理解している
- Docker無視設定ファイルの役割と書き方がわかる
🔧 Docker Composeの活用
- docker-compose.ymlの基本構造を理解している
- サービス名がコンテナ間通信で重要な理由を説明できる
- ポートマッピング(例:
3306:3306)の意味を理解している -
depends_onで起動順序を制御する方法がわかる
💾 ボリュームとデータ永続化
- バインドマウントと名前付きボリュームの違いを理解している
- 開発時にソースコードの変更を即座に反映させる方法がわかる
- データベースのデータを永続化する重要性を理解している
🚀 Rails開発環境の構築
- ホストマシンでRails環境をセットアップできる
-
rails newコマンドの各オプションの意味を理解している - 環境変数を.envファイルで管理する方法がわかる
- Docker ComposeでRailsアプリケーションを起動できる
すべての項目にチェックが入ったら、第2章へ進みましょう! チェックが入らない項目は、もう一度該当箇所を読み返してみてください。
演習問題
💪 実際にDockerコンテナを操作してみましょう! 以下の課題で、Dockerの基本操作を身につけます。
課題1: Railsコンソールを使ってみる
🎯 目標: Dockerコンテナ内でRailsコンソールを実行する
開発中、データベースの中身を確認したり、Railsの動作を試したりするために、Railsコンソールは欠かせません。 Dockerコンテナ内でRailsコンソールを起動してみましょう。
💡 ヒント(クリックで展開)
Dockerコンテナ内でコマンドを実行するには:
docker compose execを使いますwebはサービス名ですrails consoleがRailsコンソールを起動するコマンドです
✅ 答え(クリックで展開)
# Railsコンソールを起動
docker compose exec web rails console
# または省略形
docker compose exec web rails c
実行後の確認:
# Railsコンソール内で実行
Rails.version # Railsのバージョンが表示される
exit # コンソールを終了
課題2: MySQLデータベースに接続する
🎯 目標: データベースコンテナに接続してテーブルを確認する
実際のデータベースがどうなっているか確認することは重要です。 MySQLコンテナに接続して、テーブル一覧を表示してみましょう。
💡 ヒント(クリックで展開)
MySQLに接続するには:
- まず
dbコンテナに入る必要があります - MySQLクライアントで接続します
- 環境変数で設定したユーザー名とデータベース名を使います
基本的なMySQLコマンド:
SHOW DATABASES;- データベース一覧USE データベース名;- データベースを選択SHOW TABLES;- テーブル一覧
✅ 答え(クリックで展開)
# MySQLコンテナに接続
docker compose exec db mysql -u todoapp -p todo_development
# パスワードを聞かれたら「password」を入力
MySQL内で実行するコマンド:
-- 現在のデータベースを確認
SELECT DATABASE();
-- テーブル一覧を表示
SHOW TABLES;
-- スキーマ情報を確認(テーブルがある場合)
SHOW TABLES LIKE 'schema_migrations';
-- MySQLを終了
exit;
別の方法(ワンライナー):
# パスワードを含めて一行で実行
docker compose exec db mysql -u todoapp -ppassword todo_development -e "SHOW TABLES;"
まだマイグレーションを実行していない場合、テーブルは存在しません。 第2章でモデルを作成した後、再度確認してみてください。
課題3: docker-compose.ymlで.envファイルを読み込む
🎯 目標: 環境変数をより安全に管理する
現在、docker-compose.ymlには環境変数が直接書かれています。 これを.envファイルから読み込むように変更してみましょう。
💡 ヒント(クリックで展開)
docker-compose.ymlで.envファイルを読み込む方法:
env_fileディレクティブを使う- または、環境変数の値を
${変数名}で参照する
.envファイルに追加する内容:
- MySQLのパスワード
- データベース名
- ユーザー名
✅ 答え(クリックで展開)
1. .envファイルを更新:
# データベース接続情報(Rails用)
DATABASE_HOST=db
DATABASE_USER=todoapp
DATABASE_PASSWORD=password
# MySQL設定(docker-compose用)
MYSQL_ROOT_PASSWORD=rootpassword
MYSQL_DATABASE=todo_development
MYSQL_USER=todoapp
MYSQL_PASSWORD=password
2. docker-compose.ymlを更新:
services:
db:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
ports:
- "3306:3306"
command: --default-authentication-plugin=mysql_native_password
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails server -b 0.0.0.0"
volumes:
- .:/app
ports:
- "3000:3000"
depends_on:
- db
env_file:
- .env # .envファイルを読み込む
stdin_open: true
tty: true
3. 動作確認:
# コンテナを再起動
docker compose down
docker compose up
# 環境変数が正しく設定されているか確認
docker compose exec web env | grep DATABASE
- 環境ごとに異なる.envファイルを用意できる
- チーム開発で秘密情報を共有しやすくなる
- 本番環境への移行が簡単になる
📋 第1章完了!
お疲れさまでした!Docker環境の構築が完了しました。
🔨 実際にやってみましょう! 第1章の完了をコミットしておきましょう:
# 変更内容を確認
git status
# すべての変更をコミット
git add .
git commit -m "第1章完了"
第2章では、このDocker環境を使ってRails APIの本格的な開発を始めます。 Gitリポジトリの初期化とGitHubへのプッシュは第2章で詳しく説明します。