26
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

10ステップでMac OS XにRails5のDocker開発環境を構築する

Last updated at Posted at 2017-01-11

動機

私はRubyOn Railsのエンジニアです。
わたしのPCでは、rvm, macportsをつかって開発していて、rubyのバージョン管理やその他周辺ライブラリのインストールではまったりすることが多かったことから、Dockerによる開発環境の仮想化を検討しました。

Dockerについての理解

Dockerはアプリケーション(プロセス)単位で実行環境を仮想化します(アプリケーションの実行に必要なファイルやディレクトリをまとめた「コンテナ」という単位での管理)。

ウェブアプリケーションであれば、webサーバ、DBをコンテナをそれぞれ作成し、それらを連携させることで機能させることができます。

ウェブアプリでは必須の「データ」の永続化に関しては、記憶領域をコンテナにして、DBと連携させることでホストから切り離すことができます。(postgresのインストールでハマりまくったので、非常に感動しました)
Docker でデータのポータビリティをあげ永続化しよう

これを使うことで、ローカルでの開発環境の手間を省けるだけでなく、環境をイメージとして、公開し、再配布できるというメリットもあります。

ホスト環境

  • Mac OS X Yosemite (10.10.5)
  • メモリ 4G

構築する環境

  • Ruby On Rails (5.0.0)
  • Ruby (2.3.1)
  • PostgreSQL (9.5)

Docker for Macのインストール

  • https://docs.docker.com/engine/installation/mac/
    こちらに従ってインストールします。macOS 10.10.3 Yosemite or newerではDocker for Mac を、それ以外ではDocker Toolboxをインストールします。今回はDocker for Macがインストールされたものとして進めます。

コマンド

細かいコマンドの説明は省きます。以下のステップで必要なものだけ説明します

参考ページ

以下のページを参考にさせていただきました。ありがとうございました。
-Docker で Rails5 の開発環境を「rails new」から構築する
-Railsアプリケーション開発を完全にDocker化する

手順1:プロジェクトルートディレクトリの作成

まずはプロジェクトルートを作成します。今回のプロジェクト名はthinklogです。
作成したらプロジェクトルートに移動しておきます

mkdir thinklog
cd thinklog

手順2:railsをインストールするためのファイル作成

railsをinstallするためにGemfile, Gemfile.lockを作成します

touch Gemfile
touch Gemfile.lock

Gemfileは以下の内容を書きます

Gemfile
source 'https://rubygems.org'
gem 'rails', '5.0.0'

手順3:rails(webサーバコンテナ)作成用のDockerfileを作成

railsのコンテナは、docker-compose.ymlからDockerfileを参照しイメージを作成することにします。

touch Dockerfile.development
Dockerfile.development
FROM ruby:2.3.1

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

# ARG命令でdocker-compose.ymlから渡されたAPP_HOMEという引数を参照できるようにします
ARG APP_HOME

# dockerの環境側へプロジェクトルートを作成
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME

# ADD命令でホストにあるファイルをdockerの環境内にコピーします。
ADD Gemfile $APP_HOME/
ADD Gemfile.lock $APP_HOME/
RUN bundle install -j4
ADD . $APP_HOME

手順4:railsアプリケーションを構成するすべてのコンテナの定義と連携をdocker-compese.ymlにかく

ポイントは以下になります

  • webコンテナを作成するときにargsとしてカレントディレクトリを渡しており、プロジェクト名に依存しない作り
  • dataコンテナを作り、データ永続化用のコンテナをつくり、ホストの依存を断ち切っていること
  • Ctrl C でkillすると tmp/pids/server.pid が削除されず、サーバを再起動できない問題があったので以下commandの箇所を修正しました
docker-compose.yml
version: '2'
services:
  web: &app_base
    build:
      context: .
      dockerfile: "Dockerfile.development"
      args:
        - APP_HOME=${PWD}
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"

    environment:
      - "DATABASE_HOST=db"
      - "DATABASE_PORT=5432"
      - "DATABASE_USER=postgres"
      - "DATABASE_PASSWORD=mysecretpassword1234"
    volumes:
      - .:${PWD}
    ports:
      - "3000:3000"
    links:
      - db
    tty: true
    stdin_open: true
  spring:
    <<: *app_base
    command: "bundle exec spring server"
    ports: []
    tty: false
    stdin_open: false
  db:
    image: "postgres:9.5"
    environment:
      - "POSTGRES_USER=postgres"
      - "POSTGRES_PASSWORD=mysecretpassword1234"
    volumes_from:
      - data
  data:
    image: "busybox"
    volumes:
      - "/var/lib/postgresql/data"


手順5:rails newを実行して、イメージを作成する

以下のコマンドを実行すると、プロジェクトが新規作成され、それをもとにイメージが作成されます。
この段階ではまだコンテナの雛形である「イメージ」の段階です

docker-compose run --rm web rails new . --force --database=postgresql --skip-bundle

手順6:bunldle installし、Gemfile.lockを更新

rails newを実行するとGemfileがRails5のベースのGemfileに差し代わっています。
このタイミングでbundle installを実行し、Gemfile.lockを更新します.
ここではイメージ側のGemfile.lockが書き換わっただけです。

docker-compose run --rm web bundle install

手順7: 再buildし、Gemfileの更新結果をイメージに反映

これをして初めて、イメージ側にgemが反映されます。
ホスト側とイメージ側で2回bunlde installが走るのがいけてないです。
(しかもフルで走る)

docker-compose build

手順8: データベース設定

docker-compose.ymlで環境変数が渡されているのでそれを読み取るようにします。

config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch('DATABASE_USER') { 'root' } %>
  password: <%= ENV.fetch('DATABASE_PASSWORD') { 'password' } %>
  host: <%= ENV.fetch('DATABASE_HOST') { 'localhost' } %>
  port: <%= ENV.fetch('DATABASE_PORT') { 5432 } %>

development:
  <<: *default
  database: thinklog_development

test:
  <<: *default
  database: thinklog_test

production:
  <<: *default
  database: thinklog_production
  

手順9: データベース作成

docker-compose run --rm web rails db:create

手順10: 起動

docker-compose up

確認

docker ps
結果
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
e87c36fb1fa8        postgres:9.5        "/docker-entrypoint.s"   30 seconds ago      Up 12 seconds       5432/tcp                 thinklog_db_1
0e7b50b979b8        thinklog_web        "bundle exec rails s "   3 minutes ago       Up 11 seconds       0.0.0.0:3000->3000/tcp   thinklog_web_1
2ab3e48b66d2        thinklog_spring     "bundle exec spring s"   3 minutes ago       Up 11 seconds                                thinklog_spring_1

コンテナが起動しました。しかし、データボリュームコンテナは常駐していない模様...(必要な時しか起動しないのか)

でけた!!
スクリーンショット 2017-01-11 6.24.05 PM.jpg

ちなみに

コンソール起動はこれ
docker-compose run --rm web rails s

まとめ

  • ホストに依存しない環境は構築できました。しかし、docker-composeコマンドをたたかないといけなかったり bundle installを何回もしないといけないなど、デメリットもあります。
  • あと気になったのが、データボリュームコンテナは、アクセスされたタイミングで起動と終了していて、これはいいのかどうか.....
  • しかしながら一回作った環境をファイルだけで使いまわせる(ほかのメンバとシェアできる)のは大きな魅力です!今後はワーカージョブを起動したりする設定を追加していきたいと思います!!!!!
26
30
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?