Open8

RailsプロジェクトをDockerで環境構築する

kondokondo

概要

新規RailsプロジェクトをDockerで環境構築する。

kondokondo

compose.ymlの使用

docker-compose.ymlではなく、compose.ymlが推奨になった。yamlとymlについては、railsがyml(database.yml、等)なので、ymlを使用することにする。

The default path for a Compose file is compose.yaml (preferred) or compose.yml that is placed in the working directory. Compose also supports docker-compose.yaml and docker-compose.yml for backwards compatibility of earlier versions. If both files exist, Compose prefers the canonical compose.yaml.
出典:https://docs.docker.com/compose/compose-file/03-compose-file/

kondokondo

version指定は不要

compose.ymlには、version: '3'などのversion指定をよく見かける。然乍、これは単なる情報であり、Composeは実行時には最新のスキーマを用いるとのこと。むしろ記述すると、実態とズレが生じるので書かないことにした。

The top-level version property is defined by the Compose Specification for backward compatibility. It is only informative.
Compose doesn't use version to select an exact schema to validate the Compose file, but prefers the most recent schema when it's implemented.
出典:https://docs.docker.com/compose/compose-file/04-version-and-name/

kondokondo

bundleはディレクトリ内で管理する

bundle installの生成ファイルをどこで管理するか。ローカル環境であれば、bundle config set path vendor/bundleなどを用いて、そのプロジェクト内で管理する。一方でコンテナ環境であれば、グローバルにinstallしても良さそうである。
然乍、プロジェクト内で管理することにした。理由は、開発時にGemのソースコードを読むのはよくある為。そのディレクトリ内でコードを読めた方が何かと都合が良い。

kondokondo

vendor/bundleをバインドマウントから外す

以下のようにcompose.ymlを記述した。

 app:
# 略
    volumes:
      - .:/app
# 略

このままだと問題が生じる。ホストのvendor/bundleがコンテナに同期されてしまう。例えば、ローカル環境(ruby2系)でbundle installして作成されたvendor/bundleがコンテナ(ruby3系)に同期されてしまうといった問題である。
こういう場合は、ボリュームでマウントを上書きする。コンテナはホストではなく、ボリュームを参照するようになる。

 app:
# 略
    volumes:
      - .:/app
      - $PWD/vendor/bundle

Volume Trickとも呼ばれる。
https://shotat.hateblo.jp/entry/2016/12/01/221631

kondokondo

不要なファイルの同期を防ぐ

上記のVolume Trickは、高速化においても有用である。バインドマウントよりも、ボリュームの方がパフォーマンスは優れている。ホストのファイルで同期が不要なものもボリュームでマウントを上書きする。

  app:
# 略
    volumes:
      - .:/app
      - $PWD/vendor/bundle
      - $PWD/tmp
      - $PWD/log
      - $PWD/.git

https://qiita.com/shotat/items/57d049793605ffc20135

kondokondo

anonymous volumeは避ける

上記でマウントを上書きする為に、anonymous volumeを使用した。然乍、anonymous volumeはコンテナを立ち上げるために別のボリュームとして生成されるため、大量のボリュームが作成されてしまう。名前付きに変更する。

volumes:
  mysql_data:
  vendor_bundle:
  tmp:
  log:
  git:

services:
   web:
# 略
    volumes:
      - .:/tunag-education
      - vendor_bundle:$PWD/vendor/bundle
      - tmp:$PWD/tmp
      - log:$PWD/log
      - git:$PWD/.git
kondokondo

Railsコマンドが実行できない

コンテナを立ち上げる際に、/usr/local/bundleが見つからずエラーが発生する。ボリュームを作成して解消する。同期性は不要なので、cachedオプションを加えておく。

volumes:
  bundle:
# 略

services:
   web:
# 略
    volumes:
      - .:/tunag-education
      -  bundle:/usr/local/bundle:cached

https://blog.freedom-man.com/ruby-docker-bundler