Skip to content

Instantly share code, notes, and snippets.

@brianjbayer
Created November 7, 2022 22:47
Show Gist options
  • Save brianjbayer/bbdb9eb9ae98d9c2f33c9b2a65cf7798 to your computer and use it in GitHub Desktop.
Save brianjbayer/bbdb9eb9ae98d9c2f33c9b2a65cf7798 to your computer and use it in GitHub Desktop.
WIP: Rails 7 App Dockerfile
# --- Base Image ---
FROM ruby:3.1.2-slim-bullseye AS ruby-base
# --- Base Builder Stage ---
FROM ruby-base AS base-builder
# Update to match version in app Gemfile.lock
ARG BUNDLER_VER=2.3.21
# Static config
ARG APP_ROOT=/app
# Install Build Packages and Bundler
ARG BUILD_PACKAGES='build-essential libpq-dev'
RUN apt-get update \
&& apt-get -y dist-upgrade \
&& apt-get -y install ${BUILD_PACKAGES} \
&& rm -rf /var/lib/apt/lists/* \
# install bundler version
&& gem install bundler:$BUNDLER_VER
# Copy Gemfiles at minimum to bundle install
WORKDIR ${APP_ROOT}
COPY Gemfile Gemfile.lock ./
# -------------------------
# --- Dev Builder Stage ---
FROM base-builder AS dev-builder
# Update to match versions
ARG MAJOR_RUBY_VER=3.1.0
ARG BUNDLER_VER=2.3.21
ARG APP_ROOT=/app
ARG BUNDLER_PATH=/usr/local/bundle
WORKDIR ${APP_ROOT}
RUN bundle _${BUNDLER_VER}_ install \
# Remove unneeded files (cached *.gem, *.o, *.c)
&& rm -rf ${BUNDLER_PATH}/cache/*.gem \
&& find ${BUNDLER_PATH}/gems/ -name "*.c" -delete \
&& find ${BUNDLER_PATH}/gems/ -name "*.o" -delete
# --- Dev Environment Stage ---
# ASSUME source is docker volumed into the image
FROM dev-builder AS devenv
# Add git, vim, and curl at least
ARG DEVENV_PACKAGES='git vim curl'
RUN apt-get update \
&& apt-get dist-upgrade \
&& apt-get install -y ${DEVENV_PACKAGES} \
&& rm -rf /var/lib/apt/lists/*
# Start devenv in (command line) shell
CMD bash
# --------------------------
# - Deploy Builder Stage ---
# TODO: This app is still MVP
FROM base-builder AS deploy-builder
# Update to match versions
ARG MAJOR_RUBY_VER=3.1.0
ARG BUNDLER_VER=2.3.21
ARG APP_ROOT=/app
ARG BUNDLER_PATH=/usr/local/bundle
WORKDIR ${APP_ROOT}
# Run bundle install for deployment
# MVP keep assets
# RUN bundle _${BUNDLER_VER}_ config set --local without 'development:test:assets' \
RUN bundle _${BUNDLER_VER}_ config set --local without 'development:test' \
&& bundle _${BUNDLER_VER}_ install \
# Remove unneeded files (cached *.gem, *.o, *.c)
&& rm -rf ${BUNDLER_PATH}/cache/*.gem \
&& find ${BUNDLER_PATH}/gems/ -name "*.c" -delete \
&& find ${BUNDLER_PATH}/gems/ -name "*.o" -delete \
# Configure bundler to lock to Gemfile.lock
&& bundle _${BUNDLER_VER}_ config --global frozen 1
# Copy source
COPY . .
# Any Precompilation here
RUN bundle exec bin/rails assets:precompile
# Remove folders not needed in deploy image
# MVP keep assets
# RUN rm -rf node_modules tmp/cache app/assets vendor/assets spec
RUN rm -rf node_modules tmp/cache vendor/assets spec
# - Deploy Image ---
FROM ruby-base AS deploy
ARG APP_ROOT=/app
# Install runtime packages
ARG RUNTIME_PACKAGES='postgresql-client'
RUN apt-get update \
&& apt-get -y dist-upgrade \
&& apt-get -y install ${RUNTIME_PACKAGES} \
&& rm -rf /var/lib/apt/lists/*
# Add user for running app
RUN adduser --disabled-password --gecos '' deployer
USER deployer
WORKDIR ${APP_ROOT}
# Copy the built gems directory from builder layer
COPY --from=deploy-builder --chown=deployer /usr/local/bundle/ /usr/local/bundle/
# Copy the pruned app source
COPY --from=deploy-builder --chown=deployer ${APP_ROOT}/ ${APP_ROOT}/
# Run the server but allow override
ARG APP_HOST_PORT=3000
EXPOSE ${APP_HOST_PORT}
ENV RAILS_ENV=production
CMD RAILS_SERVE_STATIC_FILES= SECRET_KEY_BASE=`bin/rake secret` ./script/runserver
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment