DockerでRails + Nginx + Postgresの環境を構築する。その②

2017年12月22日

Dockerでrails5.1.4環境を構築する

 

前回の記事ではDockerをMacにインストールして、
少しDockerコンテナを起動させたり、
コンテナに繋いでDockerの操作に慣れました。

DockerでRails + Nginx + Postgresの環境を構築する。その①

今回はそのDockerでrails環境を構築して行きます。

 

 

環境構築の流れ

 

環境構築の流れは以下になります。

  1. ruby2.4.2のイメージを取得
  2. rubyのコンテナでbundle init
  3. Dockerfileを元にrailsをインストール
  4. コンテナを起動した際に、Railsが立ち上がるように設定

手順はこちらの記事を参考にしました。
RailsアプリをDockerで開発するための手順

 

 

 

 

早速構築

 

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

 

 

ブラウザから繋いでもみれます。

 

rails起動画面

 

少し開発してみる

 

せっかくコンテナが
できたので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

 

 

これで、
http://localhostに接続すれば。

ユーザ管理画面が表示されます。

ユーザ管理画面

構築は以上です。

 

 

まとめ

 

 

ここまで、railsの環境構築をしましたが、
Dockerには一プロセス一コンテナという原則みたいなものがあるので、
アプリとDBではコンテナを分ける必要があります。
(今回はsqliteを使ったので、DBと一緒のコンテナにしてます。)

 

コンテナ管理ツールとして
docker-composeというものがあるので、
次はそれを使いながら、
rails + nginx + postgres環境を構築したいと思います。