TORIPIYO DIARY

recent events, IoT, programming, security topics

dockerでrailsとpostgresqlのアプリ開発環境をローカルマシンに構築

railsアプリをローカルマシンで開発する環境をdockerで構築します。基本的に、Quickstart: Compose and Rails | Docker Documentationの内容を元にしています。

docker for macをインストール

dockerを利用するためには、もちろんdockerが必要なので、docker for macをインストールします。
Install Docker for Mac | Docker Documentation
他のサイトにもたくさん解説があると思うので、具体的なインストール方法をここでは省略します。インストールが完了して、docker for macが動いているとMacの右上のステータスバーにdockerのアイコンが表示されます。
https://docs.docker.com/docker-for-mac/images/whale-in-menu-bar.png

ちなみに、docker for macは、virtualboxlinuxマシン上にdockerエンジンを起動して動かしていると思っていたのですが、virtualboxではなくてHyperKitというテクノロジーを使っているそうです。virtualboxを利用するのは、docker toolboxということでした。
Docker for Mac vs. Docker Toolbox | Docker Documentation

railsアプリケーション用のイメージとコンテナの作成

アプリケーションで利用するrailsコンテナのイメージを、rubyのイメージから作成します。まず適当に、アプリケーションを入れるディレクトリを作成します。(sample-appとか適当な名前でいい。)ディレクトリ内にDockerfileという名前のファイルを作成します。

Dockerfile

FROM ruby:2.4.3
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

上記のファイルでは、以下を指定しています。

  • ruby2.4.3 のイメージを元に新しいイメージを作成
  • RUN apt-get ~~~ でrailsアプリケーションの実行に必要なパッケージをインストール
  • /myappディレクトリを作成して、/myapp配下で作業を行う
  • /appディレクトリ配下にGemfileとGemfile.lockを置いて必要なgemパッケージをインストール
  • gemパッケージのインストール後にアプリケーションのソースコード一式を/myapp配下に配置

次に、同じディレクトリ内に、GemfileとGemfile.lockを作成します。

Gemfile

source 'https://rubygems.org'
gem 'rails', '5.0.0.1'

Gemfile.lock

(空ファイル)

最後に、docker-compose.ymlファイルを同じディレクトリに作成します。

docker-compose.yml

version: '3'
services:
  db:
    image: postgres
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

docker-compose.ymlファイルでは、以下を指定しています。

dbコンテナ

  • postgresのイメージからdbコンテナを作成

webコンテナ

  • Dockerfileの情報を元にwebコンテナを作成
  • コンテナを立ち上げると"bundle exec rails s -p 3000 -b '0.0.0.0'"をデフォルトで実行するように設定
  • ローカルマシン上のソースコードをコンテナの/app配下で共有できるようにマウント
  • ローカルマシンの3000ポートに繋げると、コンテナ側の3000に接続されるように設定
  • webコンテナはdbコンテナが必要なので、dbコンテナが先に起動するように指定


必要なファイルを作成したら以下のコマンドをディレクトリ内で実行します。

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

上記コマンドは、docker-compose.ymlの情報をもとに、webとdbコンテナが作成され、webコンテナに"rails new . --force --database=postgresql"のコマンドを実行させています。(--forceオプションで既にあるファイルを強制的に上書き、--databaseでデータベースにpostgresqlの利用を指定。)
これで、railsアプリケーションのテンプレートがディレクトリ内に作成されるので、テンプレート内のファイルを修正して効率的に開発作業を進めることが出来ます。

webコンテナ用イメージの再ビルド

"rails new . --force --database=postgresql"の実行後、Gemfile, Gemfile.lockの内容が書き換えられるので、ファイル内容の変更が反映されたwebコンテナのイメージを作成するために、以下コマンドを実行してイメージを再度ビルドさせます。

docker-compose build

これで、webコンテナのイメージにはGemfile, Gemfile.lockファイルの更新が反映されたものになり、イメージ内ではGemfileに記述されたgemパッケージのリストがインストールされた状態になります。
開発を進めてgemを追加した場合は、その度にイメージの再ビルドが必要となります。

データベースの接続設定

ここまでの設定では、webコンテナからdbコンテナのデータベースに繋ぐ設定がまだありません。アプリケーションのルートディレクトリ以下にあるconfig/database.ymlにあるファイルを修正してデータベースに接続できるようにします。webコンテナからは、dbというホスト名でIPを取得出来るようになっているので、host:にはdbを指定しています。

database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: 5

development:
  <<: *default
  database: myapp_development


test:
  <<: *default
  database: myapp_test

これで、データベースの接続設定は完了です。必要な設定は終わったので、webとdbコンテナを起動させます。

docker-compose up -d

を実行すると(-dオプションでバックグラウンドでの起動を指定)、webとdbコンテナが起動されます。ブラウザで http://localhost:3000 に繋ぐと下記のようなWelcomeメッセージが表示されるはずです。
f:id:ha107chan:20180206224804p:plain

dbコンテナのpostgresqlにデータベースを作成するには、下記を実行すればdatabase.ymlの設定に基づいてdbコンテナにデータベースが作成されます。

docker-compose run web rake db:create

コンテナの停止

docker-compose stop

コンテナの削除
(データベースのデータもvolumeに保存していない場合は消えるので注意)

docker-compose down

です。


======================================================

以上で、ローカル環境でdockerを使ったrailsアプリ開発の基盤が出来ました。これで、ローカルマシン上でソースコードを書いていけば、webコンテナにアクセスして動作を確認しながら開発を進めていくことができます。データベースのデータを永続化出来るようにvolumeに保存するとか、設定ファイルを修正したら自動でrailsを再起動させるとか、慣れてきたら自分の設定を調べながら追加していくといいと思います。