Dockerでrails5.1.4環境を構築する
前回の記事ではDockerをMacにインストールして、 少しDockerコンテナを起動させたり、 コンテナに繋いでDockerの操作に慣れました。
- DockerでRails + Nginx + Postgresの環境を構築する。その①
- DockerでRails + Nginx + Postgresの環境を構築する。その②
- DockerでRails + Nginx + Postgresの環境を構築する。その③
今回はそのDockerでrails環境を構築して行きます。
環境構築の流れ
環境構築の流れは以下になります。
- ruby2.4.2のイメージを取得
- rubyのコンテナでbundle init
- Dockerfileを元にrailsをインストール
- コンテナを起動した際に、Railsが立ち上がるように設定
早速構築
ruby2.4.2のイメージを取得
まずはruby2.4.2がインストールされた、 イメージを取得してきます。
docker pull ruby:2.4.2
※前回の記事ですでにruby:2.4.2の取得が済んでいる人は、 ここはスキップしても大丈夫です。
rubyのコンテナでbundle init
取得したコンテナ内でbundle initして、 Gemfileを作成します。
docker run --rm -v "$PWD":/usr/src/sample -w /usr/src/sample ruby:2.4.2 bundle init
できたGemfileを編集して、 railsの行を追加してあげます。
$cat Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem "rails", '5.1.4'
Dockerfileを基にrailsアプリ用イメージの作成
次にDockerfileを用いてrailsアプリ用のイメージをビルドして行きます。 今回は下記のようなDockerfileを作成します。
FROM ruby:2.4.2
ENV APP_ROOT /usr/src/sample
WORKDIR $APP_ROOT
RUN apt-get update && \
apt-get install -y nodejs \
sqlite3 \
--no-install-recommends && \
rm -rf /var/lib/apt/lists/*
COPY Gemfile $APP_ROOT
COPY Gemfile.lock $APP_ROOT
RUN \
echo 'gem: --no-document' >> ~/.gemrc && \
cp ~/.gemrc /etc/gemrc && \
chmod uog+r /etc/gemrc && \
bundle config --global build.nokogiri --use-system-libraries && \
bundle config --global jobs 4 && \
bundle install && \
rm -rf ~/.gem
Dokcerfileとははapacheの設定ファイルのような形式で記述されたファイルになります。 ここに、 自由にイメージのビルドに必要なタスクを記述していくことで、 基のイメージから新しいイメージを作成することができます。
今回はrailsに必要なモジュールがインストールされた イメージを作成するためのDockerfileになっています。
Gemfile.lockがないので作成。
:> Gemfile.lock
ビルドのコマンドは次のように、 ビルドの基になるイメージと基底ディレクトリを指定します。
$ docker build -t version1/sample .
docker images(イメージの一覧取得)を叩くと確かに新しいイメージが作成されています。
$docker images | grep version1
version1/sample latest f31106e13371 40 seconds ago 762MB
先ほどの手順までで、 railsに必要なモジュールがインストールできたので、 作成されたイメージでrails newして行きます。
$docker run --rm -it -v "$PWD":/usr/src/sample version1/sample rails new .
このコマンドは、 カレントディレクトリをversion1/sampleイメージの/usr/src/sampleに マウントしてrails newしています。
これで、rails new できました。 ローカルでファイルをみてみるとrailsのファイル群がインストールされています。
$ls -ltr
total 64
-rw-r--r-- 1 admin staff 546 Nov 23 13:01 Dockerfile
-rw-r--r-- 1 admin staff 130 Nov 23 13:06 config.ru
-rw-r--r-- 1 admin staff 227 Nov 23 13:06 Rakefile
-rw-r--r-- 1 admin staff 374 Nov 23 13:06 README.md
drwxr-xr-x 3 admin staff 102 Nov 23 13:06 vendor
drwxr-xr-x 4 admin staff 136 Nov 23 13:06 tmp
drwxr-xr-x 11 admin staff 374 Nov 23 13:06 test
drwxr-xr-x 9 admin staff 306 Nov 23 13:06 public
-rw-r--r-- 1 admin staff 64 Nov 23 13:06 package.json
drwxr-xr-x 3 admin staff 102 Nov 23 13:06 log
drwxr-xr-x 4 admin staff 136 Nov 23 13:06 lib
drwxr-xr-x 3 admin staff 102 Nov 23 13:06 db
drwxr-xr-x 14 admin staff 476 Nov 23 13:06 config
drwxr-xr-x 10 admin staff 340 Nov 23 13:06 app
-rw-r--r-- 1 admin staff 1974 Nov 23 13:06 Gemfile
drwxr-xr-x 9 admin staff 306 Nov 23 13:06 bin
-rw-r--r-- 1 admin staff 4772 Nov 23 13:06 Gemfile.lock
コンテナを起動した際に、Railsが立ち上がるように設定
ここまででrailsが動く環境は作れましたが、 コンテナ起動と同時にRailsも立ち上がるようにしたいので、 Dockerfileに下記記述を追記します。
COPY . $APP_ROOT
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
記述を追記したら再度ビルドします。 追記した部分では、 ローカルのソースをコンテナ内の $APP_ROOTにコピーして、 3000番ポートを開けて、railsを起動しています。
docker build -t version1/sample .
これで構築は 完了なので、コンテナを起動させてみましょう。
docker run -d -p 3000:3000 -v "${PWD}:/usr/src/sample" version1/sample
※起動させる場合は、 -vコマンドでローカルのディレクトリをマウントして置くのがみそです。 これしないとローカルのソースとコンテナ内のソースが同期できないので
無事起動しました。
$docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7a0a8cfabe5 version1/sample "rails server -b 0..." 8 seconds ago Up 7 seconds 0.0.0.0:3000->3000/tcp admiring_hugle
ブラウザから繋いでもみれます。

少し開発してみる
せっかくコンテナが できたのでUserのCRUDくらいまで 作りましょう。
scaffoldする場合は、
docker exec -it c7a0a8cfabe5 bash
としてコンテナに接続してコマンドを叩いてもいいですが、 面倒なので、
docker exec c7a0a8cfabe5 rails scaffold User name email age
とすればワンコマンドでscaffoldできます。
マイグレーションも
docker exec c7a0a8cfabe5 rake db:migrate
でいけます。
config/routes.rbも少し変更して、 ユーザ管理画面がトップに来るようにします。
Rails.application.routes.draw do
resources :users
root 'users#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
config/配下を修正したので、 コンテナを再起動させます。
docker restart c7a0a8cfabe5
ユーザ管理画面が表示されます。

構築は以上です。
まとめ
ここまで、railsの環境構築をしましたが、 Dockerには一プロセス一コンテナという原則みたいなものがあるので、 アプリとDBではコンテナを分ける必要があります。 (今回はsqliteを使ったので、DBと一緒のコンテナにしてます。)
コンテナ管理ツールとして docker-composeというものがあるので、 次はそれを使いながら、 rails + nginx + postgres環境を構築したいと思います。