Skip to content

Instantly share code, notes, and snippets.

@t-richards
Created December 18, 2025 20:36
Show Gist options
  • Select an option

  • Save t-richards/bb9c08eeeb4d20912ce23a86abd02a38 to your computer and use it in GitHub Desktop.

Select an option

Save t-richards/bb9c08eeeb4d20912ce23a86abd02a38 to your computer and use it in GitHub Desktop.
# Build tools
FROM oven/bun:1.3.4-alpine AS bun
# Builder image
FROM ruby:3.4.7-alpine AS builder
ENV RAILS_ENV=production
ENV BUNDLER_VERSION=4.0.1
ENV BUNDLE_DEPLOYMENT=true
ENV BUNDLE_WITHOUT=development:test
ENV BUNDLE_JOBS=3
ENV BUNDLE_RETRY=3
ENV SECRET_KEY_BASE_DUMMY=1
WORKDIR /app
# System-level build dependencies
RUN apk add --no-cache --update alpine-sdk tzdata yaml-dev
RUN gem install bundler -v $BUNDLER_VERSION
COPY --from=bun /usr/local/bin/bun /usr/local/bin/
# App deps
COPY Gemfile* /app/
RUN bundle install
# Remove some things that cleanup_vendor doesn't get yet
RUN cd vendor/bundle/ruby/3.4.0; \
rm -rf cache; \
rm -rf gems/*/ext; \
rm -rf gems/lib/*/*.so; \
rm -rf extensions/*/*/*/mkmf.log; \
rm -rf extensions/*/*/*/gem_make.out
# Build assets
COPY . /app/
RUN bun install --frozen-lockfile
RUN bin/rails assets:precompile
RUN bin/cleanup_vendor
RUN rm -f /app/bin/cleanup_vendor
RUN rm -f /app/package.json /app/package-lock.json
RUN rm -rf /app/app/assets/builds/*
RUN rm -rf /app/log/*
RUN rm -rf /app/tmp/*
RUN rm -rf /app/node_modules
RUN rm -rf /app/vendor/assets
# Runner image
FROM ruby:3.4.7-alpine AS prod
ENV RAILS_ENV=production
ENV BUNDLER_VERSION=4.0.1
ENV BUNDLE_WITHOUT=development:test
ENV BUNDLE_PATH=vendor/bundle
WORKDIR /app
# Add app
COPY --from=builder /app /app
RUN set -eux; \
# Runtime dependencies
apk add --no-cache --update curl ca-certificates jemalloc patchelf tzdata yaml; \
# Patch ruby binary to use jemalloc without LD_PRELOAD
patchelf --add-needed libjemalloc.so.2 /usr/local/bin/ruby; \
apk del patchelf; \
# Install bundler
gem install bundler -v $BUNDLER_VERSION; \
rm -rf /root/.gem; \
# Verify deps
bundle check; \
# Pre-populate bootsnap cache
bundle exec bootsnap precompile --gemfile app/ lib/; \
rm -f log/*; \
# Add unprivileged user and allow it to write to tmp
adduser --disabled-password app; \
chown -R app:app tmp
EXPOSE 3000
USER app
ENTRYPOINT ["/app/bin/rails"]
CMD ["server"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment