Engineering

Nov 23, 2017

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

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

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

  1. DockerでRails + Nginx + Postgresの環境を構築する。その①
  2. DockerでRails + Nginx + Postgresの環境を構築する。その②
  3. 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

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

 

Screen-Shot-2017-11-23-at-13.24.29.png

 

少し開発してみる

 

せっかくコンテナが できたので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に接続すれば。

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

Screen-Shot-2017-11-23-at-14.07.19.png

構築は以上です。

まとめ

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

 

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

関連記事

記事検索

気になるサイト内の記事を検索する

プロフィール

バンクーバー在住のフルスタックエンジニアです。React, Ruby on Rails, Go などでお仕事しています。職場がトロントなので日本、トロント、バンクーバーの三つの時天空を操って生活しています。

プロモーション