こんにちは。Enjoy IT Life管理人の仁科(@nishina555)です。
前回、ローカル環境でRuby on RailsのWebアプリ(以下Railsアプリ)を構築・起動する方法について『Railsの開発環境構築はこれでOK!rbenvの導入からRailsアプリ起動までの詳細手順』の記事で紹介をしました。
記事中でも紹介をしましたが、rbenvでrubyを管理することでRailsアプリで利用するrubyのバージョンを簡単に変更することができます。
今回は、前回紹介したRailsアプリの環境構築・起動をDockerを利用しておこなう方法について紹介します。
Dockerを利用することで、ローカルでrubyの環境を準備しなくてもRailsアプリを起動できるようになります。

こんな方の参考になればと思います。
なお、今回の開発環境はDocker DesktopがインストールされたmacOS、作成するRailsアプリ名はrails_app、rubyのバージョンは2.6.3となっています。
目次
Gemfileの用意
まずは作業ディレクトリの作成・移動をします。
$ mkdir rails_app
$ cd rails_app
Railsアプリで利用するgemはbundlerでインストールします。
RailsアプリのDockerイメージを作成するにあたり、まずはbundlerで利用するGemfileを作成します。
$ docker run --rm -v `pwd`:/rails_app -w /rails_app ruby:2.6 bundle init
docker run
のオプションの意味は以下のようになっています。
docker runのオプション
オプション | 内容 |
–rm | Dockerコンテナ終了後、自動でコンテナを削除する |
-v | ディレクトリのマウント(ホストとDokcerのディレクトリを同期) |
-w | 作業ディレクトリの指定 |
上記のdocker run
コマンドがやっていることをまとめると以下のようになります。
- ruby:2.6のDockerイメージから作成したDockerコンテナの/rails_app上でbundle initを実行
- コマンド実行後コンテナを削除
- ローカルのカレントディレクトリとDockerコンテナの/rails_appのディレクトリを同期させる。
図を用いてコマンドの説明すると以下のようになります。

上記の説明からわかるように、ローカル環境に作成されるGemfileはDocker環境のruby・bundlerを利用しています。
ローカルに開発用のツールをインストールしなくてもアプリ開発ができるのはDockerを利用する大きなメリットです。
さて、先ほど作成されたGemfileですが、Gemfileの gem "rails"
の部分のコメントアウトを外します。
Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
- # gem "rails"
+ gem "rails"
railsが実行できるDockerイメージの作成
次に、ローカル環境のGemfileを利用して、gemがインストールされたDockerイメージを作成します。
まず、以下のようなDockerファイルを用意しましょう。
$ vim Dockerfile
Dockerfile
# ruby:2.6のDockerイメージをベースとして利用
FROM ruby:2.6
# 作業ディレクトリを/rails_appに指定
WORKDIR /rails_app
# ローカルのGemfileをDokcerにコピー
COPY Gemfile /rails_app/Gemfile
# /rails_appディレクトリ上でbundle install
RUN bundle install
上記のDockerfileをビルドしてDockerイメージを作成します。
カレントディレクトリに存在するDockerファイルからrails_appというDockerイメージを作成します。
$ docker build -t rails_app .
ビルド終了後、以下のようにDockerイメージが作成されていればOKです。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
rails_app latest bff5950f754a 27 seconds ago 924MB
Dockerイメージからコンテナを作成し、実際にデータが存在しているか確認してみましょう。例としてbundle list
を実行してみます。
$ docker run --rm rails_app bundle list
Gems included by the bundle:
* actioncable (5.2.3)
* actionmailer (5.2.3)
* actionpack (5.2.3)
* actionview (5.2.3)
...
...
(以下略)
Docker環境でgemの一覧が参照できることから、先ほど用意したDockerファイルから作成したイメージではbundle install
が実行されていることがわかります。
Railsアプリの作成
ここまででrailsが実行できるDockerイメージが作成できました。
次に、作成したDockerイメージを利用してrails new
を実行し、Railsアプリの雛形を作成します。
なお、-B
はbundle install
の実行をスキップするオプションです。
$ docker run --rm -v `pwd`:/rails_app rails_app rails new . -B
上記のコマンドの解説をします。
ローカル環境のカレントディレクトリとDocker環境の/rails_appをマウントさせることで、Docker環境にあるファイル・ディレクトリをローカルに同期しています。
また、bundle install
ですが、このあとDockerイメージを再度ビルドするときに実行されるため、rails new
をするこのタイミングでは-B
オプションでスキップしています。
さて、ローカル環境を確認すると、先ほどローカル環境とDocker環境のディレクトリをマウントしたため、Railsアプリのディレクトリ構成がローカル環境に構築されていることがわかります。
.
├── Dockerfile
├── Gemfile
├── README.md
├── Rakefile
├── app
├── bin
├── config
├── config.ru
├── db
├── lib
├── log
├── package.json
├── public
├── storage
├── test
├── tmp
└── vendor
また、bundlerでインストールしたgemはDocker環境の”/usr/local/bundle”に保存されています。
“/usr/local/bundle”はマウント対象のディレクトリではないため、ローカル環境にはbundlerでインストールしたgemは存在していません。
Railsアプリを起動するDockerイメージの作成
ここまででRailsアプリの作成が完了しました。
ここからはDockerファイルを編集し、『Railsアプリが起動するDockerイメージ』を作成します。
先ほど作成したDockerファイルを以下のように編集します。Railsアプリの起動に必要な最低限のものだけを用意しています。
Dockerfile
FROM ruby:2.6
+ RUN apt-get update -qq && apt-get install -y nodejs
WORKDIR /rails_app
COPY Gemfile /rails_app/Gemfile
RUN bundle install
+ COPY . /rails_app
# Start the main process.
+ CMD ["rails", "server", "-b", "0.0.0.0"]
以下の内容がDockerファイルに追加されています。
- Railsアプリの起動に必要なパッケージ(nodejs)のインストール
- ローカル環境のディレクトリ(rails newで作成された一式)をDocker環境にコピー
- rails serverコマンドでRailsアプリを起動
なお、rails server
では-b
でバインドするIPアドレス(応答をするIPアドレス)の指定できます。
Dockerファイルでは0.0.0.0
(ワイルドカード)を指定しているため、どのIPアドレスでリクエストがきても応答するようになっています。
Dockerファイルを作成したら再度ビルドします。
$ docker build -t rails_app .
今回のDockerイメージから生成したコンテナにはRailsアプリのディレクトリが構築されていることがわかります。
$ docker run --rm rails_app ls
Dockerfile README.md bin db package.json test
Gemfile Rakefile config lib public tmp
Gemfile.lock app config.ru log storage vendor
Railsアプリの起動
先ほど作成したDockerイメージからコンテナを作成し、Railsアプリを起動させましょう。
-p [ホストのポート]:[コンテナのポート]
でホストとDockerコンテナのポートをマッピング(ポートフォワーディング)できます。
また、-v
でディレクトリをマウントさせた状態で起動することで『ローカル環境で修正したソースコードがDocker環境のRailsアプリにも反映される』『Docker環境のGemfile.lockが更新された際にローカル環境のGemfile.lockも自動更新される』といったことが可能になります。
$ docker run --rm -p 3000:3000 -v `pwd`:/rails_app rails_app
上記のコマンドの場合、『ローカル環境の3000番ポートにアクセス = Docker環境の3000番ポートにアクセス』となります。
localhost:3000
にアクセスして以下のような画面が出ればOKです。

まとめ: Dockerはローカル開発環境構築の手間が省ける便利ツール
以上でDocker環境でRailsアプリを起動する手順について紹介を終わります。
Dockerを利用することで、ローカル環境にrbenv, ruby, bundlerなどの用意をせずにRailsアプリの開発をすることができるようになりました。
- Dockerのrubyイメージを利用してbundle initを実行し、Gemfileを作成
- bundle installを実行したDockerイメージを作成
- railsがインストールされたDockerイメージを利用してrails new
- rails serverを実行するDockerイメージを作成
- Dockerコンテナをポートフォワーディングさせた状態で起動し、ブラウザにアクセス
この記事がいいなと思いましたらツイッター(@nishina555)のフォローもよろしくお願いします!