はじめに
「Dockerって最近でもないけどよく聞くけど、正直何が嬉しいのかよく分からない...」
「環境構築はrbenvとHomebrewで十分じゃない?」
「Dockerって難しそうだし、学習コスト高そう...」
X年前の私もまったく同じことを思っていました。
しかし、Rails 6のECサイトとRails 7の管理システムを同時開発することになり、
環境管理地獄に陥った私は、ついにDockerに手を出しました。
結果:なぜもっと早く使わなかったのか... と後悔しています。
この記事では、「今更Dockerについて聞けない」という方向けに、
実際のプロジェクトを例に、Dockerの本当のメリットを解説します。
この記事の想定読者
- 複数のRailsプロジェクトを掛け持ちしている開発者
- チーム開発で環境構築に苦労している方
- MacでRails開発をしている方
- Dockerを実践的に使いたい方
動作環境
- macOS Monterey以降
- Docker Desktop 4.x
- Rails 6.1 / 7.0
- MySQL 8.0 / 8.1
🎯 この記事で得られること
- Macのローカル環境を汚さずに複数プロジェクトを管理する方法
- バージョン違いのRails/MySQLプロジェクトを瞬時に切り替える手法
- チーム開発での環境構築時間を10分以内に短縮する実践的な設定
なぜMacでDockerを使うべきか?実際に起きた3つの問題
問題1: ローカル環境の汚染
# こんなコマンドの履歴、見覚えありませんか?
$ brew install mysql@5.7
$ brew uninstall mysql@8.0
$ brew link mysql@5.7
# Error: mysql@5.7 is already installed...
MacのHomebrewで複数バージョンのMySQLを管理するのは想像以上に大変です。
問題2: 新メンバーの環境構築地獄
新しいメンバーがジョインした際の実際の会話:
- 「MySQLのバージョンは8.0.23です」
- 「Redisは6.2を使ってください」
- 「ImageMagickも必要です」
- 「あ、Node.jsは16系で...」
結果:環境構築に丸一日かかることも。
問題3: "私の環境では動くんですけど..."問題
開発環境の微妙な差異による不具合は、デバッグ時間を大幅に奪います。
Dockerで実現する理想的な開発環境
実際のプロジェクト構成
~/projects/
├── ec-site/ # Rails 6.1 + MySQL 8.0
│ ├── docker-compose.yml
│ ├── Dockerfile
│ └── ...
└── admin-system/ # Rails 7.0 + MySQL 8.1
├── docker-compose.yml
├── Dockerfile
└── ...
実践編:Rails 6 + MySQL 8.0 プロジェクトの構築
Step 1: Dockerfileの作成
FROM ruby:3.0.6-slim
# 必要なパッケージをインストール
RUN apt-get update -qq && apt-get install -y \
build-essential \
libpq-dev \
nodejs \
yarn \
git \
curl \
libmariadb-dev \
&& rm -rf /var/lib/apt/lists/*
# 作業ディレクトリを設定
WORKDIR /app
# GemfileとGemfile.lockをコピー
COPY Gemfile Gemfile.lock ./
# bundlerのバージョンを固定
RUN gem install bundler:2.2.33
RUN bundle install
# アプリケーションのコードをコピー
COPY . .
# entrypointスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
Step 2: docker-compose.ymlの設定
version: '3.8'
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: ec_site_development
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 10s
retries: 10
redis:
image: redis:6.2-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails server -b 0.0.0.0"
volumes:
- .:/app:cached # Mac用のパフォーマンス最適化
- bundle_data:/usr/local/bundle
- /app/node_modules # node_modulesは除外
ports:
- "3000:3000"
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
environment:
DATABASE_HOST: db
DATABASE_USERNAME: root
DATABASE_PASSWORD: password
REDIS_URL: redis://redis:6379/0
stdin_open: true
tty: true
volumes:
mysql_data:
redis_data:
bundle_data:
Step 3: entrypoint.shの作成
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /app/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
Step 4: database.ymlの設定
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV.fetch("DATABASE_USERNAME", "root") %>
password: <%= ENV.fetch("DATABASE_PASSWORD", "password") %>
host: <%= ENV.fetch("DATABASE_HOST", "localhost") %>
development:
<<: *default
database: ec_site_development
test:
<<: *default
database: ec_site_test
Rails 7 + MySQL 8.1 プロジェクトの構築
Rails 7プロジェクトでは、いくつかの違いがあります:
FROM ruby:3.2.2-slim
# Rails 7特有の設定
RUN apt-get update -qq && apt-get install -y \
build-essential \
libpq-dev \
nodejs \
yarn \
git \
curl \
libmariadb-dev \
# Rails 7でimport mapsを使う場合
&& curl -sL https://deb.nodesource.com/setup_18.x | bash - \
&& apt-get install -y nodejs \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Rails 7.0系
COPY Gemfile Gemfile.lock ./
RUN gem install bundler:2.4.10
RUN bundle install
COPY . .
EXPOSE 3001
CMD ["rails", "server", "-b", "0.0.0.0", "-p", "3001"]
version: '3.8'
services:
db:
image: mysql:8.1
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: admin_system_development
ports:
- "3307:3306" # ポートを変更
volumes:
- mysql_data_admin:/var/lib/mysql
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails server -b 0.0.0.0 -p 3001"
volumes:
- .:/app:cached
- bundle_data_admin:/usr/local/bundle
- /app/node_modules
ports:
- "3001:3001" # ポートを変更
depends_on:
- db
environment:
DATABASE_HOST: db
DATABASE_USERNAME: root
DATABASE_PASSWORD: password
RAILS_ENV: development
volumes:
mysql_data_admin:
bundle_data_admin:
ポート番号を変えることで、両方のプロジェクトを同時に起動できます!
実際の開発フロー
初回セットアップ(新メンバーの場合)
# プロジェクトをクローン
$ git clone https://github.com/your-team/ec-site.git
$ cd ec-site
# Docker環境を構築・起動(これだけ!)
$ docker-compose build
$ docker-compose run --rm web rails db:create db:migrate db:seed
$ docker-compose up
# ブラウザでhttp://localhost:3000にアクセス
所要時間:約10分(従来の手動セットアップ:1〜2時間)
日常の開発作業
# ECサイトプロジェクトの作業
$ cd ~/projects/ec-site
$ docker-compose up
# http://localhost:3000で開発
# 管理システムに切り替え(同時起動も可能)
$ cd ~/projects/admin-system
$ docker-compose up
# http://localhost:3001で開発
# 両方同時に起動することも可能!
よく使うコマンド集
# Railsコンソール
$ docker-compose exec web rails console
# マイグレーション実行
$ docker-compose exec web rails db:migrate
# テスト実行
$ docker-compose exec web bundle exec rspec
# Gemの追加
$ docker-compose exec web bundle add [gem_name]
$ docker-compose build # Dockerfileの再ビルドが必要な場合
# ログの確認
$ docker-compose logs -f web
# 全てのコンテナを停止・削除
$ docker-compose down
# ボリュームも含めて削除(DBデータも消える)
$ docker-compose down -v
docker-compose down -vを実行するとDBのデータも削除されます。本当に必要な時だけ使いましょう。
Dockerを使った開発の5つの決定的なメリット
1. 完全な環境の分離
# Mac本体
$ mysql --version
# zsh: command not found: mysql ← Macには何もインストールされていない!
# ECサイトプロジェクト
$ docker-compose exec db mysql --version
# mysql Ver 8.0.33 for Linux on x86_64
# 管理システムプロジェクト
$ docker-compose exec db mysql --version
# mysql Ver 8.1.0 for Linux on x86_64
2. 環境構築の圧倒的な速さ
| 項目 | 従来の方法 | Docker |
|---|---|---|
| 初回セットアップ | 1-2時間 | 10分 |
| 別PCへの環境移行 | 30分-1時間 | 10分 |
| トラブルシューティング | 不定(最悪1日) | docker-compose down -v で解決 |
3. チーム全体の生産性向上
- 新人エンジニア:「環境構築で詰まることなく、初日からコードが書けました」
- ベテランエンジニア:「環境系の質問対応が激減し、コードレビューに集中できます」
- プロジェクトマネージャー:「環境差異によるバグがゼロになりました」
4. 本番環境との一貫性
# 本番用Dockerfile(一部抜粋)
FROM ruby:3.0.6-slim
# ... 開発環境と同じベースイメージ
開発環境と本番環境の差異を最小限に抑えることで、「本番でだけ起きる問題」を大幅に削減。
5. 実験的な変更が容易
# MySQL 8.2を試したい
$ vim docker-compose.yml
# image: mysql:8.0 → mysql:8.2
$ docker-compose down
$ docker-compose up
# 問題があれば即座に戻せる
$ git checkout docker-compose.yml
$ docker-compose down && docker-compose up
トラブルシューティング
よくある問題と解決方法
Q1: ポート番号が既に使用されているエラー
# Error: bind: address already in use
$ lsof -i :3000 # 使用中のプロセスを確認
$ kill -9 [PID] # 該当プロセスを終了
Q2: Dockerのディスク容量不足
# 不要なイメージ・コンテナを削除
$ docker system prune -a
Q3: bundle installが遅い
# docker-compose.ymlでボリュームマウントを活用
volumes:
- bundle_data:/usr/local/bundle # gemをキャッシュ
Q4: M1/M2 Macでのplatform関連エラー
# docker-compose.ymlに追加
services:
db:
platform: linux/amd64 # M1/M2 Mac対応
image: mysql:8.0
パフォーマンスチューニング
Mac特有の最適化
services:
web:
volumes:
# :cachedオプションでパフォーマンス向上
- .:/app:cached
- bundle_data:/usr/local/bundle
# node_modulesは除外
- /app/node_modules
Docker Desktopの設定
- Docker Desktop → Preferences → Resources
- CPUs: 4以上を推奨
- Memory: 8GB以上を推奨
- Disk image size: 60GB以上
Docker Desktopは無料で使えますが、大企業(従業員数250名以上または年間収益$10M以上)での商用利用には有料ライセンスが必要です。
まとめ:もう「今更」なんて言わせない
実際に2つのRailsプロジェクトを並行開発して実感したDockerのメリット:
✅ 環境構築時間を90%削減(2時間→10分)
✅ 環境起因のバグをゼロに
✅ チーム全体の生産性が向上
✅ Macのローカル環境をクリーンに保てる
✅ 異なるバージョンのプロジェクトを瞬時に切り替え可能
最初は「Dockerって難しそう...」と思うかもしれません。しかし、一度この環境を体験すると、もう元の開発スタイルには戻れません。
特に複数プロジェクトを掛け持ちするフリーランスエンジニアや、チーム開発を行うスタートアップには、Dockerは必須のツールと言えるでしょう。
「今更Dockerなんて...」と思っていた過去の自分に言いたい。「今すぐ始めろ」と。
🎯 実際に使ってみた感想・フィードバック歓迎
この設定で実際にプロジェクトを動かしてみた方は、ぜひコメントで感想を教えてください!
特に以下の点について情報交換できると嬉しいです:
- M1/M2 Macでのパフォーマンス
- Windows WSL2での動作確認
- より効率的な設定方法
次のステップ
- まずは既存プロジェクトの1つをDocker化してみる
- docker-composeの基本コマンドを覚える
- CI/CDパイプラインにDockerを組み込む
- Kubernetes(k8s)への移行を検討
📚 参考リンク
この記事が役に立ったら、ぜひLGTMとストックをお願いします!
チームメンバーにもシェアして、みんなでDocker化を進めましょう🐳
執筆者
株式会社ユーコン
CEO 植村圭志
http://ucon.net/