Пришёл в Ruby из C#, Docker вроде знаю, но тут образ получается 1,4 ГБ, и деплой тянет его по 4 минуты. Dockerfile писали до меня: полный ruby:3.3, всё одним слоем, apt-get install с компиляторами. Rails 8.0, PostgreSQL. С чего начать?
С многоступенчатой сборки. Компиляторы, заголовки и кэш gem'ов нужны только при bundle install и сборке ассетов, в финальный образ они попадать не должны. Генератор Rails с 7.1 кладёт хороший Dockerfile, можно взять его за основу. Суть:
FROM ruby:3.3-slim AS base
WORKDIR /rails
ENV BUNDLE_PATH=/usr/local/bundle BUNDLE_DEPLOYMENT=1 BUNDLE_WITHOUT=development:test
FROM base AS build
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
COPY Gemfile Gemfile.lock ./
RUN bundle install && rm -rf ~/.bundle "${BUNDLE_PATH}"/ruby/*/cache
COPY . .
RUN SECRET_KEY_BASE_DUMMY=1 bin/rails assets:precompile
FROM base
RUN apt-get update -qq && apt-get install -y libpq5 && rm -rf /var/lib/apt/lists/*
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /rails /rails
CMD ["./bin/thrust", "./bin/rails", "server"]
И .dockerignore, чтобы в образ не уехали log, tmp, node_modules и .git.
По примеру собрал на slim в две стадии. Было 1,4 ГБ, стало 310 МБ. Образ тянется меньше чем за минуту, а если менялся только код, секунд за десять: слой с gem'ами берётся из кэша. Заодно выяснилось, что в образ ехала папка с дампами базы для разработки, ещё 300 МБ.