Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce the size of the deployed docker image from >350MB to 277MB #3894

Merged
merged 2 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
/reports/*

# Ignore storage (uploaded files in development and any SQLite databases).
/storage/*
Expand All @@ -27,6 +28,14 @@
!/app/assets/builds/.keep
/public/assets

# Ignore tests
/test/

# Ignore files that are generated by the build process.
# /config/database.yml.sample
/config/versions.list
/vendor/toxic_domains_whole.txt

# From before
.git*
.github*
Expand Down
96 changes: 59 additions & 37 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,23 @@ RUN --mount=type=cache,id=dev-apk-cache,sharing=locked,target=/var/cache/apk \
bash \
tzdata \
xz-libs \
gcompat
gcompat \
zstd-libs \
libpq

# Rails app lives here
RUN mkdir -p /app /app/config /app/log/

# Set production environment
ENV BUNDLE_APP_CONFIG=".bundle_app_config"
ENV MAGIC="/usr/share/misc/magic.mgc"

# Update rubygems
ARG RUBYGEMS_VERSION
RUN gem update --system ${RUBYGEMS_VERSION} --no-document
RUN gem update --system ${RUBYGEMS_VERSION} --no-document && \
# rubygems-update is completely unused after the `gem update --system` process
gem uninstall rubygems-update -x && \
# Remove rubygems cache files, they are unused
rm -r /usr/local/bundle/cache/ /root/.local/share/gem/

# Throw-away build stage to reduce size of final image
FROM base as build
Expand All @@ -36,62 +41,73 @@ RUN \
apk add \
nodejs \
postgresql-dev \
ca-certificates \
build-base \
bash \
libmagic \
zstd-libs \
linux-headers \
zlib-dev \
tzdata
tzdata

WORKDIR /app

ENV RAILS_ENV="production"

# Install application gems
COPY Gemfile* /app/
RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor \
bundle config set --local without 'development test' && \
bundle config set --local path /srv/vendor && \
bundle install --jobs 20 --retry 5 && \
bundle exec bootsnap precompile --gemfile && \
bundle clean && \
mkdir -p vendor && \
bundle config set --local path vendor && \
cp -ar /srv/vendor . && \
rm -fr /app/vendor/ruby/*/cache
RUN --mount=type=cache,id=bld-gem-cache,sharing=locked,target=/srv/vendor <<BASH
set -ex

bundle config set --local without 'development test'
bundle config set --local path /srv/vendor
bundle install --jobs 20 --retry 5
bundle clean
mkdir -p vendor
bundle config set --local path vendor
cp -ar /srv/vendor .

# Remove .gem files
rm -r /app/vendor/ruby/*/cache

# Remove gem extension build logs
rm /app/vendor/ruby/*/extensions/*/*/*/gem_make.out

# Remove avo source maps (8+ MB!)
rm /app/vendor/ruby/*/gems/avo-*/public/avo-assets/*.js.map

# Remove ruby 2.x source code
find /app/vendor/ruby/*/gems/debase-ruby_core_source-*/lib/debase/ruby_core_source -maxdepth 1 -type d -name 'ruby-2.*' -exec rm -r {} \;

# Remove datadog precompiled binaries for other platforms
find /app/vendor/ruby/*/gems/libdatadog-*/vendor/libdatadog-*/ -mindepth 1 -maxdepth 1 -not -name "$(ruby -e 'puts RbConfig::CONFIG["arch"]')" -exec rm -r {} \;
BASH


# Copy application code
COPY . /app/

# Precompile bootsnap code for faster boot times
RUN bundle exec bootsnap precompile app/ lib/
RUN mv /app/config/database.yml.sample /app/config/database.yml

COPY --link config/database.yml.sample /app/config/database.yml

# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN RAILS_GROUPS=assets SECRET_KEY_BASE=1234 bin/rails assets:precompile

RUN bundle config set --local without 'development test assets' && \
# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN <<BASH
set -ex
RAILS_GROUPS=assets SECRET_KEY_BASE=1234 bin/rails assets:precompile
rm -r /app/tmp/cache/assets/
BASH

RUN <<BASH
set -ex
bundle config set --local without 'development test assets'
bundle clean --force
rm -r /app/tmp/cache/bootsnap/
# Precompile bootsnap code for faster boot times, but do it after weve
segiddins marked this conversation as resolved.
Show resolved Hide resolved
# removed the assets group for minimal precompilation size
bundle exec bootsnap precompile --gemfile app/ lib/
BASH


# Final stage for app image
FROM base

RUN --mount=type=cache,id=dev-apk-cache,sharing=locked,target=/var/cache/apk \
--mount=type=cache,id=dev-apk-lib,sharing=locked,target=/var/lib/apk \
apk add \
libpq \
libmagic \
zstd-libs \
ca-certificates \
bash \
tzdata \
xz-libs

RUN mkdir -p /app
WORKDIR /app

Expand All @@ -100,12 +116,18 @@ RUN mkdir -p tmp/pids
# Copy built application from previous stage
COPY --link --from=build /app/ /app/

ADD https://s3-us-west-2.amazonaws.com/oregon.production.s3.rubygems.org/versions/versions.list /app/config/versions.list
ADD https://s3-us-west-2.amazonaws.com/oregon.production.s3.rubygems.org/stopforumspam/toxic_domains_whole.txt /app/vendor/toxic_domains_whole.txt
ADD --link https://s3-us-west-2.amazonaws.com/oregon.production.s3.rubygems.org/versions/versions.list /app/config/versions.list
ADD --link https://s3-us-west-2.amazonaws.com/oregon.production.s3.rubygems.org/stopforumspam/toxic_domains_whole.txt /app/vendor/toxic_domains_whole.txt

ARG REVISION
RUN echo "${REVISION}" > REVISION

# Stop bootsnap from writing to the filesystem, we precompiled it in the build stage
ENV BOOTSNAP_READONLY=true

# Needed since we install the gem and then move it to a new location
ENV MAGIC="$(find /app/vendor/ruby/*/gems/ruby-magic-*/ -name magic.mgc | head -n1)"

EXPOSE 3000

# Ensures ruby commands are run with bundler
Expand Down