Help us understand the problem. What is going on with this article?

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に変えて実行しましょう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした