7
13

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 3 years have passed since last update.

【Rails】Dockerで環境構築をする方法

Posted at

開発環境

・Docker: 19.03.8
・Docker-Compose: 1.25.5
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina

実装

1.作業ディレクトリを作成・移動

フォルダ名はmyapp(なんでもいい)として進めていきます。

ターミナル
$ mkdir myapp
ターミナル
$ cd myapp

2.Dockerfileを作成・編集

ターミナル
$ vi Dockerfile
Dockerfile
FROM ruby:2.7.1
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

# コンテナー起動時に毎回実行されるスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# メインプロセスの起動
CMD ["rails", "server", "-b", "0.0.0.0"]

【解説】

★ 概要

FROM : 使用するイメージとバージョンを設定
RUN : コマンドの実行
WORKDIR : 作業ディレクトリを設定
COPY : ローカルのファイルをコンテナへコピー
ENTRYPOINT : 一番最初に実行するコマンドを設定
EXPOSE : コンテナがリッスンするport番号を設定
CMD : イメージ内部のソフトウェア実行

★ 詳細

◎ 使用するイメージとして、2020/7/19現在最新安定版を取得する。

FROM ruby:2.7.1

◎ Node.jsとPostgreSQLのパッケージをインストールする。

RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

◎ コンテナ内にmyappディレクトリを作成する。

RUN mkdir /myapp

◎ 作業ディレクトリを、上記で作成したmyappに設定する

WORKDIR /myapp

◎ ローカルのGemfileを、コンテナ内のmyappへコピーする。

COPY Gemfile /myapp/Gemfile

◎ ローカルのGemfile.lockを、コンテナ内のmyappへコピーする。

COPY Gemfile.lock /myapp/Gemfile.lock

bundle installを実行する。

RUN bundle install

◎ カレントディレクトリ(ローカルのmyapp)を、コンテナ内のmyappへコピーする。

. = カレントディレクトリ

COPY . /myapp

◎ ローカルのentrypoint.shを、コンテナ内のusr/binへコピーする。

COPY entrypoint.sh /usr/bin/

◎ 上記でコピーしたentrypoint.shへの、アクセス権限を許可する。

RUN chmod +x /usr/bin/entrypoint.sh

◎ コンテナを立ち上げた際に、1番最初に実行されるコマンドとしてentrypoint.shを設定する。

ENTRYPOINT ["entrypoint.sh"]

◎ ポート番号を3000に設定する。

EXPOSE 3000

◎ Railsサーバーを立ち上げる。

CMD ["rails", "server", "-b", "0.0.0.0"]

3.Gemfileを作成・編集

Railsのバージョン指定を行います。
今回はRails6に対応するようにしていきます。

ターミナル
$ vim Gemfile
Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 6'

4.Gemfile.lockを作成

ターミナル
$ touch Gemfile.lock

5.entrypoint.shを作成・編集

ターミナル
$ vi entrypoint.sh
entrypoint.sh
#!/bin/bash
set -e

# Rails に対応したファイル server.pid が存在しているかもしれないので削除する。
rm -f /myapp/tmp/pids/server.pid

# コンテナーのプロセスを実行する。(Dockerfile 内の CMD に設定されているもの。)
exec "$@"

5.docker-compose.ymlを作成・編集

ターミナル
$ vi docker-compose.yml
docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  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

【解説】

version : docker-composeのバージョンを設定する。
services : この下のハッシュにサービスを作る。命名は自由だが、通常はwebとdbと名付ける。
image : 使用するimage(dbでPostgreSQLを指定)
volumes : ディレクトリのマウント設定(dbデータなどを残せる)
build : Dockerfileなどがあるパス(基本的にカレントディレクトリ)
command : コマンド(server.pidファイルを削除してからrailsサーバー起動)
ports : ポート番号(ホスト:コンテナで設定)
depends_on : 依存関係を示していて、起動順を指定できる。ここではdb→webへと起動する。

6.ディレクトリ構造を確認

ターミナル
myapp
- Dockerfile
- Gemfile
- Gemfile.lock
- entrypoint.sh
- docker-compose.yml

7.プロジェクトをビルド

ターミナル
$ docker-compose run web rails new . --force --no-deps --database=postgresql --skip-bundle

【解説】

--force : Gemfileを上書き
--no-deps : リンクしたサービスを起動しない
--database=postgresql : DBにPostgreSQLを指定
--skip-bundle : bundleをスキップ

8.bundle installを実行

ターミナル
Could not find gem 'pg (>= 0.18, < 2.0)' in any of the gem sources listed in your Gemfile.
Run `bundle install` to install missing gems.

7 で上記のようなエラーが出たかと思うので、解決する為に下記コマンドを実行します。
Dockerイメージををビルドする際に、bundle installしてくれます。

ターミナル
$ docker-compose build

9.database.ymlを編集

config/database.yml
# 変更前
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

# 変更後
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password
  pool: 5

10.コンテナを起動

ターミナル
$ docker-compose up

※下記エラーが出る場合

ターミナル
Error: No such file or directory @ rb_sysopen - /myapp/config/webpacker.yml (RuntimeError)

webpacker.ymlを作成・編集

ターミナル
touch config/webpacker.yml
webpacker.yml
# Note: You must restart bin/webpack-dev-server for changes to take effect

default: &default
  source_path: app/javascript
  source_entry_path: packs
  public_root_path: public
  public_output_path: packs
  cache_path: tmp/cache/webpacker
  webpack_compile_output: true

  # Additional paths webpack should lookup modules
  # ['app/assets', 'engine/foo/app/assets']
  additional_paths: []

  # Reload manifest.json on all requests so we reload latest compiled packs
  cache_manifest: false

  # Extract and emit a css file
  extract_css: true

  static_assets_extensions:
    - .jpg
    - .jpeg
    - .png
    - .gif
    - .tiff
    - .ico
    - .svg
    - .eot
    - .otf
    - .ttf
    - .woff
    - .woff2

  extensions:
    - .mjs
    - .js
    - .sass
    - .scss
    - .css
    - .module.sass
    - .module.scss
    - .module.css
    - .png
    - .svg
    - .gif
    - .jpeg
    - .jpg

development:
  <<: *default
  compile: true

  # Set to false if using HMR for CSS
  extract_css: true

  # Reference: https://webpack.js.org/configuration/dev-server/
  dev_server:
    https: false
    host: localhost
    port: 3035
    public: localhost:3035
    hmr: false
    # Inline should be set to true if using HMR
    inline: true
    overlay: true
    compress: true
    disable_host_check: true
    use_local_ip: false
    quiet: false
    pretty: false
    headers:
      'Access-Control-Allow-Origin': '*'
    watch_options:
      ignored: '**/node_modules/**'

test:
  <<: *default
  compile: true

  # Compile test packs to a separate directory
  public_output_path: packs-test

production:
  <<: *default

  # Production depends on precompilation of packs prior to booting for performance.
  compile: false

  # Cache manifest.json for performance
  cache_manifest: true

11.データベースを作成

ターミナル
docker-compose run web rake db:create

※下記エラーが出る場合

ターミナル
could not translate host name "db" to address: Name or service not known
ターミナル
Error: Database is uninitialized and superuser password is not specified.

docker-compose.ymlを編集

docker-compose.yml
# 変更前
environment:
  POSTGRES_PASSWORD: password

# 変更後
environment:
  - POSTGRES_HOST_AUTH_METHOD=trust
7
13
0

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
7
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?