slidict.io では、alpine + rails を使用しています。 slidict.io で使用しているdockerコンテナを解説していきたいと思います。
Docker Image
alpineはパッケージを追加しても軽量で抑えられるため使っています。クラウドでコンテナレジストリの容量に気を遣う場面も多いのも理由です。
FROM ruby:3.1.2-alpine3.16 as builder
ARG RAILS_ENV
ENV RAILS_ENV=$RAILS_ENV
ENV TZ "UTC"
RUN \
apk add --no-cache yarn npm && \
apk add --no-cache build-base libffi-dev --virtual .build
RUN npm install -g npx
WORKDIR "/app"
FROM builder
COPY . .
RUN \
bundle config --local path vendor/bundle && \
bundle install && \
bundle config frozen true && \
bundle config set --local clean 'true'
RUN yarn install --check-file
RUN \
if [ "$RAILS_ENV" != "development" -a "$RAILS_ENV" != "" ] ; then \
apk del --purge .build; \
fi
RUN bundle exec rails tmp:create
RUN \
if [ "$RAILS_ENV" != "development" -a "$RAILS_ENV" != "" ] ; then \
yarn build:css; \
bundle exec rails assets:precompile --trace; \
fi
CMD ["/bin/sh", "/app/entrypoint.sh"]
EXPOSE 3000
上記は、 railsの軌道に最低限必要なDockerfileです。
利用する上での注意する点、知っておいたほうが良い点があります。
rails_helper.rbの修正
docker-composeなどで環境が指定できるようにします。
ARG RAILS_ENV
ENV RAILS_ENV=$RAILS_ENV
上記方法だけだとtestを走らせたときに支障が出てきます。そのため以下のような修正をrails_helper.rbに行う必要が出てきます。
-ENV['RAILS_ENV'] ||= 'test'
+ENV['RAILS_ENV'] = ENV['RAILS_ENV'].present? ? ENV['RAILS_ENV'] : 'test'
multi-stage build
FROM ruby:3.1.2-alpine3.16 as builder
.....
.....
.....
FROM builder
multi-stage buildを使用してdocker buildの時間を短縮するようにしています。docker build単体ではmulti-stage buildを使用する必要がありませんが、docker buildxを使用するときに必要になってきます。
bundle install
RUN \
bundle config --local path vendor/bundle && \
bundle install && \
bundle config frozen true && \
bundle config set --local clean 'true'
docker build時にbundle installするようにしています。path を vendor/bundle 配下にしているのは、docker-compose 実行時にホスト側で見れるようにするためです。
開発環境別スクリプト
RUN \
if [ "$RAILS_ENV" != "development" -a "$RAILS_ENV" != "" ] ; then \
apk del --purge .build; \
fi
.....
.....
.....
RUN \
if [ "$RAILS_ENV" != "development" -a "$RAILS_ENV" != "" ] ; then \
yarn build:css; \
bundle exec rails assets:precompile --trace; \
fi
development環境では、新たにbundleを追加する場面があるのでビルドパッケージをインストールしています。また開発環境以外ではアセットのコンパイルをするようにしています(開発環境では後述のentrypoint.shでアセットのコンパイルなどをしています。
entrypoint
CMD ["/bin/sh", "/app/entrypoint.sh"]
entrypoint.shを独自に作成して起動時に実行するようにしています。想定では開発環境以外で実行され、開発環境ではdocker-compose.ymlで開発環境用のentrypoint.shが実行されます。
entrypoint.sh
#!/bin/bash
set -e
bundle exec pumactl start
Dockerが立ち上がった際のentrypointを指定します。pumactlでrailsを立ち上げてます。
docker-compose.yml
networks:
app-tier:
driver: bridge
services:
rails: &rails
tty: true
stdin_open: true
environment:
- EDITOR=vi
- RAILS_ENV=
build:
context: .
dockerfile: Dockerfile
volumes:
- ./:/app
working_dir: /app
command: "sh entrypoint.local.sh"
ports:
- 3000:3000
networks:
- app-tier
rspec:
<<: *rails
ports:
- 5000:3000
command: "sh entrypoint.local.sh"
depends_on:
- rails
開発環境用のdocker-compose.shです。
entrypoint.local.sh
#!/bin/sh
set -e
bundle config --global --delete without
bundle config --global --delete frozen
bundle install
yarn install --check-files
bin/rails log: clear
bin/rails db:seed
bin/rails assets:clobber
yarn build --watch < /dev/zero &
yarn build:css --watch &
bundle exec pumactl start
docker-compose実行に使用する開発環境用のentrypoint用のファイルです
コメントを残す