シンプルなRailsアプリを作って、それをDockerで動かすためのDockerfileを書いてみた。
こんなかんじ:

FROM ruby:2.6.3-alpine3.9 AS builder

ENV RAILS_ENV production

WORKDIR /app

RUN apk add --update --no-cache \
    build-base \
    libxml2-dev \
    libxslt-dev \
    sqlite-dev \
    nodejs \
    yarn \
    tzdata

# install gems
RUN gem install bundler
COPY Gemfile .
COPY Gemfile.lock .
RUN bundle install --clean --frozen --jobs $(nproc) --without development test

# install npm packages
COPY package.json .
COPY yarn.lock .
RUN yarn install --frozen-lockfile

# compile assets
COPY Rakefile .
COPY bin bin
COPY .browserslistrc .
COPY postcss.config.js .
COPY babel.config.js .
COPY config config
COPY app/assets app/assets
COPY app/javascript app/javascript
RUN bin/rails assets:precompile


FROM ruby:2.6.3-alpine3.9

ENV RAILS_ENV production
ENV RAILS_LOG_TO_STDOUT 1
ENV RAILS_SERVE_STATIC_FILES 1

WORKDIR /app

RUN apk add --update --no-cache \
    sqlite-libs \
    tzdata

COPY --from=builder /usr/local/bundle /usr/local/bundle
COPY --from=builder /app/public/assets /app/public/assets
COPY --from=builder /app/public/packs /app/public/packs
COPY . .

RUN bin/rails db:schema:load

EXPOSE 3000
ENTRYPOINT ["bin/rails"]

あと.dockerignoreはこうした:

.bundle
.dockerignore
.git
.gitignore
Dockerfile
log
node_modules
public/assets
public/packs
README.md
storage
test
tmp

  • マルチステージビルドを使って、ビルドステージではgemのインストールとassets:precompileを行う。
  • 次のステージでRailsサーバを動かすためだけの最小限のファイルをコピーする。
これでイメージサイズが160Mくらい。もう少し小さくできそうな気もする。
あとDBとか他のサーバと合わせて動かすとどうなるかちょっと分かってない。