Rails の Dockerfile の自分なりのベストプラクティス
概要
この度、Dockerfile, docker-compose.yml を見直してみました。
その際に調べたことのメモです。
試す、見直すこと
- Dockerfile 見直し
- ruby alpine イメージを試す
- bundle config 周りの見直し
- docker-compose で bundle を volume するか見直し
Dockerfile ベストプラクティス
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/ Dockerfileを書くときに気をつけていること10選
In Docker 1.10 and higher, only the instructions RUN, COPY, ADD create layers. Other instructions create temporary intermediate images, and do not directly increase the size of the build.
- RUN, COPY, ADD はまとめる
Sort multi-line arguments
- アルファベット順に
Although ADD and COPY are functionally similar, generally speaking, COPY is preferred.
- COPY を使う
ruby alpine イメージを試す について
ruby alpine と google/protobuf の間でバグがあるようで、使用を見送りました。
https://github.com/google/protobuf/issues/4460
bundle config 周りについて
ruby の公式イメージは /usr/local/bundle です。
BUNDLE_PATH を vender/bundle などに変更すべきなのかわからず。。。container におけるベストプラクティスはどうなのだろう。
docker-compose で bundle を volume するか見直し
docker build は時間がかかるので、gem 更新時は docker-compose run app bundle install できた方がいいと感じました。
cached や delegated については遅く感じ始めたら対応する方針で良いかと。
https://docs.docker.com/compose/compose-file/#caching-options-for-volume-mounts-docker-for-mac
まとめ
一旦、こんな感じがベストなのかなと。
FROM ruby:2.5.1
ENV LANG C.UTF-8
ENV APP_HOME /home/app
WORKDIR $APP_HOME
COPY Gemfile* ./
RUN apt-get update -qq && apt-get install -y --no-install-recommends \
build-essential \
mysql-client \
curl -sL https://deb.nodesource.com/setup_10.x | bash - && apt-get install -y nodejs && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
gem install bundler && \
bundle install
COPY . .
EXPOSE 3000
CMD ["bundle", "exec", "rails", "server", "-p", "3000", "-b", "0.0.0.0"]
version: '3'
services:
mysql:
image: mysql:5.7.19
environment:
- MYSQL_ROOT_PASSWORD=root
ports:
- "3307:3306"
volumes:
- db-data:/var/lib/mysql
app:
build: .
image: my-rails/app
environment:
RAILS_ENV: development
volumes:
- .:/home/app
- bundle-data:/usr/local/bundle
ports:
- "3000:3000"
depends_on:
- mysql
volumes:
bundle-data:
db-data: