From b16c3a83a23c92ecfd218976c32a0de1578dbedf Mon Sep 17 00:00:00 2001 From: David Taylor Date: Wed, 19 Aug 2026 13:16:58 +0000 Subject: [PATCH] PERF: Reduce compressed base image size by ~68MB (~5%) - ~19MB - Mount tmpfs when installing nginx. Matches other apt steps in the docker file - Same for postgres/redis, so that the 19MB doesn't move to their layer - ~6MB - Mount tmpfs over /root/.cache when installing pups. `gem fetch` downloads the whole RubyGems spec index - ~43MB - Set `install_extension_in_lib: false` in gemrc. By default RubyGems stores every compiled gem extension twice: once in extensions/ and again in the gem's own lib/. The extensions/ copy is the one that is actually used. This is planned to become the RubyGems 4 default: https://github.com/ruby/rubygems/issues/8921 - Pass `--package-import-method hardlink` to pnpm install. This does not change the size of our CI builds, which already hardlink. But it stops pnpm using reflinks on supported filesystems (btrfs, XFS, OrbStack). If reflinks are used, they are lost during the packaging process, so we silently double the cost of node_modules. --- image/base/Dockerfile | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/image/base/Dockerfile b/image/base/Dockerfile index d58217595..df9d836d4 100644 --- a/image/base/Dockerfile +++ b/image/base/Dockerfile @@ -128,7 +128,10 @@ RUN sed -i "s/^# $LANG/$LANG/" /etc/locale.gen &&\ locale-gen # nginx -RUN apt update &&\ +RUN --mount=type=tmpfs,target=/var/log \ + --mount=type=tmpfs,target=/var/cache/apt \ + --mount=type=tmpfs,target=/var/lib/apt \ + apt update &&\ DEBIAN_FRONTEND=noninteractive apt-get -y install \ nginx-light \ libnginx-mod-http-brotli-filter \ @@ -182,7 +185,8 @@ COPY --from=oxipng-builder /usr/local/bin/jhead /usr/local/bin COPY --from=oxipng-builder /usr/local/bin/oxipng /usr/local/bin # version check: https://rubygems.org/gems/pups -RUN cd /tmp &&\ +RUN --mount=type=tmpfs,target=/root/.cache \ + cd /tmp &&\ gem fetch pups --version 1.4.0 &&\ echo "5809731d6f4819defe1aac694e614c4b3d9958b5f378a70edf761f3808877052 pups-1.4.0.gem" | sha256sum -c &&\ gem install --local --force pups-1.4.0.gem &&\ @@ -222,6 +226,12 @@ RUN --mount=type=tmpfs,target=/var/log \ # node nodejs +# Do not copy built C extensions into each gem's lib/ as well as extensions/. +# RubyGems keeps both by default (Gem.install_extension_in_lib); the extensions/ +# dir is authoritative and comes first in require_paths. Slated to become the +# default in RubyGems 4: https://github.com/ruby/rubygems/issues/8921 +RUN echo "install_extension_in_lib: false" >> /usr/local/etc/gemrc + # pnpm RUN --mount=type=tmpfs,target=/root/.npm \ npm install -g pnpm@10 @@ -245,10 +255,12 @@ RUN cd /var/www/discourse &&\ find /var/www/discourse/vendor/bundle -name tmp -type d -exec rm -rf {} + RUN cd /var/www/discourse &&\ - sudo -u discourse /bin/bash -c 'pnpm install --frozen-lockfile' + sudo -u discourse /bin/bash -c 'pnpm install --frozen-lockfile --package-import-method hardlink' FROM discourse-web-only AS discourse-release RUN --mount=type=tmpfs,target=/var/log \ + --mount=type=tmpfs,target=/var/cache/apt \ + --mount=type=tmpfs,target=/var/lib/apt \ apt-get -y update && DEBIAN_FRONTEND=noninteractive apt-get -y install \ - postgresql-${PG_MAJOR} postgresql-contrib-${PG_MAJOR} postgresql-${PG_MAJOR}-pgvector -RUN apt-get -y update && DEBIAN_FRONTEND=noninteractive apt-get -y install redis + postgresql-${PG_MAJOR} postgresql-contrib-${PG_MAJOR} postgresql-${PG_MAJOR}-pgvector \ + redis