()
RailsのDocker環境作成
開発関連技術
開発環境, Docker, Ruby, Rails
Rails チュートリアルを勉強したかったので、Docker 公式を参考に Docker 環境を作成しました。
その際に少しやり方を変えたのと、いくつかエラーに遭遇したので、そのメモを書いておきます。
前提#
- Docker 導入済み
 - docker-compose コマンドが使用できる
 
なお、この記事の手順では Rails 5系の環境となる点に注意です。
Docker 環境#
作成手順#
※2021/02/07追記 少し公式の手順が変わっていたので見直しを行いました。
公式では、すべてのファイルをルートに置いていますが、自分は以下のようなディレクトリ構造にしたかったので変えました。
自分の場合のディレクトリ構造はこちら。
(root)
├ docker
│ └ ruby
│     └ Dockerfile
├ ※Railsのソース
├ docker-compose.yml
├ entrypoint.sh
├ Gemfile
├ Gemfile.lock
└ README.md- Dockerfile を作成
 
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /src
WORKDIR /src
COPY Gemfile /src/Gemfile
COPY Gemfile.lock /src/Gemfile.lock
RUN bundle install
COPY . /src
# 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"]- Gemfile を作成
 
source 'https://rubygems.org'
gem 'rails', '~>5'- 
Gemfile.lock を作成(中身は空で OK)
 - 
entrypoint.sh を作成
 
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /src/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"- docker-compose.yml を作成
 
version: '3.9'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  web:
    build:
      context: ./
      dockerfile: ./docker/ruby/Dockerfile
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/src
    ports:
      - "3000:3000"
    depends_on:
      - db※Windows の場合は、下記の注意点も参照。
- ビルドして、Rails プロジェクトを作成
 
docker-compose run --no-deps web rails new . --force --database=postgresql- もう一度、コンテナをビルド(rails new で Gemfile の内容が変わったため)
 
docker-compose build- データベースの接続設定を記述(src/config/database.yml)
データベース名は任意の名前で OK。 
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
  <<: *default
  database: myapp_development
test:
  <<: *default
  database: myapp_testDocker の起動#
- コンテナの起動
 
docker-compose up -d- 初期 DB の作成
 
docker-compose exec web rails db:create以下のように表示されれば無事データベースが作成されています。
Created database 'myapp_develop'
Created database 'myapp_test'- ブラウザでアクセス
 
localhost:3000以下のような画面が表示されればOKです。
遭遇したエラー#
ビルドコンテキスト外のファイルを COPY しようとしてエラー#
docker-compose.yml の以下の部分。
web:
  build:
    context: ./
    dockerfile: ./docker/ruby/Dockerfile最初はこうしていました。
web:
  build: ./docker/rubyすると、Dockerfile の中で、Gemfile を COPY するところでエラーになりました。
原因としては、ビルドコンテキスト外のファイルで COPY や ADD ができないとのことでした。
つまりビルドコンテキストに./docker/rubyを指定しているので、この配下にあるファイルしか指定できないようです。
なので、buildの個所をcontextとdockerfileにわけて記述することで対応しました。
なお、補足として、Dockerfile の COPY などで指定するホスト側のパスは、ビルドコンテキストを基準としたパスになります。
COPY Gemfile /src/Gemfile ← ビルドコンテキスト(./)からのパスコンテナ起動時に exited with code 1 になる#
docker-compose up で起動するとコンテナがうまく起動しませんでした。
原因としては、コンテナ起動時に実行しているentrypoint.shの改行コードがCRLF(Windows標準)になっていたことでした。
ここは改行コードをLF(Linux標準)に変更して対応しました。
Windows のみで発生するエラー#
postgres コンテナの起動に失敗する#
コンテナ起動に失敗し、ログを見るとFATAL: data directory "/var/lib/postgresql/data" has wrong ownershipと表示されて
いました。
どうも volume マウントに失敗していたようです。
docker-compose.yml でマウントのパスを/var/lib/postgresql/dataから/var/lib/postgresql/に修正すると、なぜか起動するようになりました。
db:
  image: postgres
  volumes:
    - ./tmp/db:/var/lib/postgresql/ ← パス末尾の data をなくすRails アプリが File exists @ dir_s_mkdir - /src/tmp/cache/assets/sprockets/v3.0/2D でエラー落ちする#
一度はちゃんと動作していた Rails アプリがこのエラーになり、動作しなくなったことがありました。
どうも Windows の場合は、ファイルの大文字小文字を区別しないことにより、ファイル名称がバッティングしてしまい起こるそうです。
参考記事の通りに対応することで解決しました。
src/config/initializers/assets.rb に以下を追加。
Rails.application.config.assets.configure do |env|
  env.cache = Sprockets::Cache::FileStore.new(
    ENV.fetch("SPROCKETS_CACHE", "#{env.root}/tmp/cache/assets"),
    Rails.application.config.assets.cache_limit,
    env.logger
  )
enddocker-compose.yml を以下のように修正。
version: '3.9'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql
    environment:
      POSTGRES_PASSWORD: password
  web:
    build:
      context: ./
      dockerfile: ./docker/ruby/Dockerfile
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    environment:
      - SPROCKETS_CACHE=/cach
    volumes:
      - .:/src
      - cache:/cache
    ports:
      - "3000:3000"
    depends_on:
      - db
volumes:
  cache:Docker 公式で案内があったのはありがたかったのですが、ディレクトリ構造を変更したこともあり、いくつかエラーに遭遇しました。
とりあえず無事起動できてよかったです。
Rails チュートリアルは一応一通り終わったので、一旦 AWS の勉強に戻ります。
資格取らねば…。


