search
LoginSignup
124

More than 3 years have passed since last update.

posted at

updated at

DockerでのRuby on Rails環境構築を一つずつ詳解する

結論

Docker公式の「Quickstart: Compose and Rails」に書いてます。
なのでスラスラ理解できる方は下記リンク先へどうぞ
https://docs.docker.com/compose/rails/

公式のクイックスタートは全部英語で書かれていて、
知能の低い僕は疲れてしまいますので
こちらの公式ガイドを少しずつ紐解きながら環境構築します。

http://docs.docker.jp/glossary.html
http://docs.docker.jp/engine/articles/dockerfile_best-practice.html
こちらのdockerガイドとベストプラクティス集が詳しい、かつ分かりやすいです。

Dockerとは?

多くの方々が分かりやすくDocker、コンテナ技術について解説してくれてますので
そちらを読みましょう。

<解説リンク>
https://knowledge.sakura.ad.jp/13265/
https://qiita.com/kotaro-dr/items/b1024c7d200a75b992fc

Dockerfile

Dockerfile
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

これをとりあえず使ってね!らしい。
しかしなんとなくで使うのは気持ち悪いのでコマンドを見ていく。

[FROM] 使用するイメージとバージョン
[RUN] コマンドの実行。railsに必要な必要なnodejsとpostgeqsqlをインストールしている
[WORKDIR] そのままの意味。作業ディレクトリを設定します。
[COPY] ローカルのファイルをコンテナへコピーする
[ENTRYPOINT] 一番最初に実行するコマンド(ここではentrypoint.shを参照)
[EXPOSE] コンテナがリッスンするport番号
[CMD] イメージ内部のソフトウェア実行(つまりRailsのことですね)

Gemfile

Gemfile
source 'https://rubygems.org'
gem 'rails', '~>5'

rails newをするとGemfileはrails用に書き換えられます。
バージョンは適宜変更しましょう。

Gemfile.lock

空の状態でGemfile.lockファイルを作ります。

$ touch Gemfile.lock

entrypoint.sh

entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

set -e は 「エラーが発生するとスクリプトを終了する」オプション
rm ではrailsのpidを削除
exec "$@"でCMDで渡されたコマンドを実行しています。(rails s)

docker-compose.yml

公式によるとdocker-composeは魔法が起こる場所らしいです(ステキ

docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

一番重要であろうdocker-compose.ymlです。
docker-composeについてもdockerガイドに分かりやすい説明が記載されています。

こちらも何が起こっているか見ていきましょう。

[version] docker-composeのバージョンです。2019年4月現在最新は'3'です。
[services] この下のハッシュにサービスを作りましょう。なんでも良いですが通常はwebとdbと名付けます。
[image] 使用するimage
[volumes] ディレクトリのマウント設定(dbデータなどを残せます。。)
[build] Dockerfiletなどがあるパス(基本的にカレントディレクトリ)
[command] コマンド(pid削除してからrails s)
[ports] ポート番号。[ホスト:コンテナ]で設定。
[depends_on] 依存関係を示していて、起動順を制御できます。ここではdb→webへと起動します。

volumeについては
https://qiita.com/gounx2/items/23b0dc8b8b95cc629f32
を参考にしました。

Rails newしよう!

Dockerfile, docker-compose.yml, entrypoint.sh, Gemfile, Gemfile.lock
が揃ったのでrails newします。

$ docker-compose run web rails new . --force --no-deps --database=postgresql --skip-bundle

DBはpostgresql、Gemfileがあるためforce(上書き)オプション付き
--no-depsはリンクしたサービスを起動しない設定。
最後にbundleしますのでここではbundleをskipします。
webのimageがビルドされてその中でrails newコマンドが実行されます。

bundle install

Gemfileが更新されたのでビルドを実行しましょう

$ docker-compose build

Rails側のDB設定

config/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

config/database.ymlを上記の通りに変更します。
Railsはデフォルトでhost:localhostとなりますので
hostを先ほど作成したdbに変更します。

コンテナの起動

$ docker-compose up

docker-compose.yml通りにdbサービスが起動し、webサービスが起動します。

DB作成

$ docker-compose run web rake db:create

あとはdb:createすれば完了です。
マイグレーションする必要があるときは上のコマンドをdb:migrateに変えて実行しましょう。

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
What you can do with signing up
124