Skip to content

Commit e928eb1

Browse files
Space and Time Reduction (#60)
This is a pass to reduce build times and image sizes. The impact varies but the general expectation is improvement. Image size reductions of 18% - 30% and build time reductions of 7% - 35% were found. Some results were greater yet less consistent and should not be expected. Changes to achieve this include: * Caching introduced for `apt`, `npm`, `go`, static `ffmpeg` builds * `apt` configuration changed to prevent automatic cache removal and to preserve downloads * Recommended `apt` packages are no longer installed * Removal of unused packages Manual testing was done. Further testing is requested to verify impact and functionality. Particularly of interest are differing and constrained environments such as CI/CD pipelines. --- <!-- mesa-description-start --> ## TL;DR Reduced Docker image sizes and build times by implementing widespread caching for `apt`, `npm`, `go`, and `ffmpeg` builds. ## Why we made these changes To reduce build times and image sizes for faster, more efficient CI/CD pipelines and local development. Image size reductions of 18% - 30% and build time reductions of 7% - 35% were observed in testing. ## What changed? - **Implemented Widespread Caching:** Introduced Docker BuildKit cache mounts (`--mount=type=cache`) across multiple Dockerfiles to cache dependencies for `apt`, `npm`, `go`, and static `ffmpeg` builds. - **Optimized `apt` Usage:** Configured `apt` to retain its cache and consistently used the `--no-install-recommends` flag to prevent installing unnecessary packages, minimizing image size. - **Improved FFmpeg Reliability:** Added MD5 checksum validation to the FFmpeg download process to ensure integrity. - **Refined Package Lists:** Removed unused packages and added essential ones like `gpg-agent` to ensure build reliability. - **Configuration:** Added `.mise.toml` to `.gitignore`. ## Validation Manual testing was done. Further testing is requested to verify impact and functionality, particularly in differing and constrained environments such as CI/CD pipelines. <sup>_Description generated by Mesa. [Update settings](https://app.mesa.dev/onkernel/settings/pull-requests)_</sup> <!-- mesa-description-end --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Introduces BuildKit caching and apt optimizations across Dockerfiles, adds FFmpeg checksum/caching, trims packages, and ignores .mise.toml to reduce build times and image sizes. > > - **Dockerfiles**: > - **Caching**: > - Add BuildKit cache mounts for `go mod download`, `go build`, `npm install/build`, and `apt`. > - Cache static `ffmpeg` downloads with MD5 verification and reuse. > - **apt optimization**: > - Preserve apt caches; use `--no-install-recommends` consistently; add `gpg-agent` where needed. > - **Package set**: > - Remove unused userland packages in headful image; split and minimize installs (e.g., `sqlite3`). > - **Chromium/Node**: > - Keep Chromium via PPA; copy Node 22 toolchain; cache global npm installs where applied. > - **Xorg build stages**: > - Use apt cache mounts and `--no-install-recommends` for `xorg-deps` and `xf86-input-neko` builds. > - **Repo**: > - Update `.gitignore` to ignore `.mise.toml`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 05a63a1. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent a0dca70 commit e928eb1

File tree

6 files changed

+142
-62
lines changed

6 files changed

+142
-62
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,6 @@ infra/tests/*
185185

186186
# Unikraft
187187
.unikraft
188+
189+
# mise-en-place
190+
.mise.toml

images/chromium-headful/Dockerfile

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@ ENV CGO_ENABLED=0
77

88
COPY server/go.mod ./
99
COPY server/go.sum ./
10-
RUN go mod download
10+
RUN --mount=type=cache,target=/root/.cache/go-build \
11+
--mount=type=cache,target=/go/pkg/mod \
12+
go mod download
1113

1214
COPY server/ .
1315

1416
# Build kernel-images API
15-
RUN GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} \
17+
RUN --mount=type=cache,target=/root/.cache/go-build \
18+
--mount=type=cache,target=/go/pkg/mod \
19+
GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} \
1620
go build -ldflags="-s -w" -o /out/kernel-images-api ./cmd/api
1721

1822
# Build chromium launcher
@@ -23,19 +27,22 @@ RUN GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} \
2327
FROM node:22-bullseye-slim AS client
2428
WORKDIR /src
2529
COPY images/chromium-headful/client/package*.json ./
26-
RUN npm install
30+
RUN --mount=type=cache,target=/root/.npm npm install
2731
COPY images/chromium-headful/client/ .
28-
RUN npm run build
32+
RUN --mount=type=cache,target=/root/.npm npm run build
2933

3034
# xorg dependencies
3135
FROM docker.io/ubuntu:22.04 AS xorg-deps
3236
WORKDIR /xorg
3337
ENV DEBIAN_FRONTEND=noninteractive
34-
RUN set -eux; \
38+
RUN --mount=type=cache,target=/var/cache/apt,sharing=private,id=ubuntu2204-aptcache \
39+
--mount=type=cache,target=/var/lib/apt,sharing=private,id=ubuntu2204-aptlib \
40+
rm -f /etc/apt/apt.conf.d/docker-clean; \
41+
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache; \
42+
set -eux; \
3543
apt-get update; \
36-
apt-get install -y \
37-
git gcc pkgconf autoconf automake libtool make xorg-dev xutils-dev \
38-
&& rm -rf /var/lib/apt/lists/*;
44+
apt-get --no-install-recommends -y install \
45+
git gcc pkgconf autoconf automake libtool make xorg-dev xutils-dev;
3946
COPY images/chromium-headful/xorg-deps/ /xorg/
4047
# build xf86-video-dummy v0.3.8 with RandR support
4148
RUN set -eux; \
@@ -61,9 +68,14 @@ FROM docker.io/ubuntu:22.04
6168
ENV DEBIAN_FRONTEND=noninteractive
6269
ENV DEBIAN_PRIORITY=high
6370

64-
RUN apt-get update && \
71+
RUN --mount=type=cache,target=/var/cache/apt,sharing=private,id=ubuntu2204-aptcache \
72+
--mount=type=cache,target=/var/lib/apt,sharing=private,id=ubuntu2204-aptlib \
73+
rm -f /etc/apt/apt.conf.d/docker-clean; \
74+
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache; \
75+
apt-get update && \
6576
apt-get -y upgrade && \
66-
apt-get -y install \
77+
apt-get --no-install-recommends -y install \
78+
gpg-agent \
6779
# UI Requirements
6880
xvfb \
6981
xterm \
@@ -95,38 +107,55 @@ RUN apt-get update && \
95107
software-properties-common && \
96108
# Userland apps
97109
sudo add-apt-repository ppa:mozillateam/ppa && \
98-
sudo apt-get install -y --no-install-recommends \
99-
libreoffice \
110+
sudo apt-get --no-install-recommends -y install \
100111
x11-apps \
101-
xpdf \
102-
gedit \
103-
xpaint \
104112
tint2 \
105-
galculator \
106-
pcmanfm \
107113
wget \
108114
xdg-utils \
109115
libvulkan1 \
110116
fonts-liberation \
111-
unzip && \
112-
apt-get clean
117+
unzip;
113118

114119
# install ffmpeg manually since the version available in apt is from the 4.x branch due to #drama.
115120
# as of writing these static builds will be the latest 7.0.x release.
116-
RUN set -eux; \
117-
URL="https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz"; \
118-
echo "Downloading FFmpeg static build from $URL"; \
119-
curl -fsSL "$URL" -o /tmp/ffmpeg.tar.xz; \
120-
tar -xJf /tmp/ffmpeg.tar.xz -C /tmp; \
121-
install -m755 /tmp/ffmpeg-*/ffmpeg /usr/local/bin/ffmpeg; \
122-
install -m755 /tmp/ffmpeg-*/ffprobe /usr/local/bin/ffprobe; \
121+
RUN --mount=type=cache,target=/tmp/cache/ffmpeg,id=ffmpeg \
122+
<<-'EOT'
123+
set -eux
124+
URL="https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz"
125+
echo "Downloading FFmpeg MD5 checksum"
126+
if ! curl --connect-timeout 10 -fsSL "${URL}.md5" -o /tmp/cache/ffmpeg/ffmpeg.tar.xz.md5; then
127+
echo "Failed to connect to ffmpeg static build provider for MD5 checksum."
128+
echo "Checking for cached version to use."
129+
if [ ! -f /tmp/cache/ffmpeg/ffmpeg.tar.xz.md5 ]; then
130+
echo "Unable to locate cached MD5 checksum. Exiting."
131+
exit 1
132+
else
133+
echo "Found cached MD5 checksum."
134+
fi
135+
fi
136+
sed -i -e 's/ .*$/ \/tmp\/cache\/ffmpeg\/ffmpeg.tar.xz/' /tmp/cache/ffmpeg/ffmpeg.tar.xz.md5
137+
echo "Checking cache for FFmpeg archive and validating MD5 checksum"
138+
if md5sum --check /tmp/cache/ffmpeg/ffmpeg.tar.xz.md5; then
139+
echo "Checksum validated, using cached FFmpeg archive"
140+
else
141+
echo "Downloading FFmpeg static build from $URL"
142+
curl -fsSL "$URL" -o /tmp/cache/ffmpeg/ffmpeg.tar.xz
143+
echo "Validating MD5 checksum of FFmpeg static build download"
144+
md5sum --check /tmp/cache/ffmpeg/ffmpeg.tar.xz.md5
145+
fi
146+
tar -xJf /tmp/cache/ffmpeg/ffmpeg.tar.xz -C /tmp
147+
install -m755 /tmp/ffmpeg-*/ffmpeg /usr/local/bin/ffmpeg
148+
install -m755 /tmp/ffmpeg-*/ffprobe /usr/local/bin/ffprobe
123149
rm -rf /tmp/ffmpeg*
150+
EOT
124151

125152
# runtime
126153
ENV USERNAME=root
127-
RUN set -eux; \
154+
RUN --mount=type=cache,target=/var/cache/apt,sharing=private,id=ubuntu2204-aptcache \
155+
--mount=type=cache,target=/var/lib/apt,sharing=private,id=ubuntu2204-aptlib \
156+
set -eux; \
128157
apt-get update; \
129-
apt-get install -y --no-install-recommends \
158+
apt-get --no-install-recommends -y install \
130159
wget ca-certificates python2 supervisor xclip xdotool \
131160
pulseaudio dbus-x11 xserver-xorg-video-dummy \
132161
libcairo2 libxcb1 libxrandr2 libxv1 libopus0 libvpx7 \
@@ -138,7 +167,7 @@ RUN set -eux; \
138167
# install libxcvt0 (not available in debian:bullseye)
139168
ARCH=$(dpkg --print-architecture); \
140169
wget http://ftp.de.debian.org/debian/pool/main/libx/libxcvt/libxcvt0_0.1.2-1_${ARCH}.deb; \
141-
apt-get install --no-install-recommends ./libxcvt0_0.1.2-1_${ARCH}.deb; \
170+
apt-get --no-install-recommends install ./libxcvt0_0.1.2-1_${ARCH}.deb; \
142171
rm ./libxcvt0_0.1.2-1_${ARCH}.deb; \
143172
#
144173
# workaround for an X11 problem: http://blog.tigerteufel.de/?p=476
@@ -153,14 +182,17 @@ RUN set -eux; \
153182
/home/$USERNAME/.local/share/xorg; \
154183
chmod 1777 /var/log/neko; \
155184
chown $USERNAME /var/log/neko/ /tmp/runtime-$USERNAME; \
156-
chown -R $USERNAME:$USERNAME /home/$USERNAME; \
157-
# clean up
158-
apt-get clean -y; \
159-
rm -rf /var/lib/apt/lists/* /var/cache/apt/
185+
chown -R $USERNAME:$USERNAME /home/$USERNAME;
160186

161187
# install chromium and sqlite3 for debugging the cookies file
162-
RUN add-apt-repository -y ppa:xtradeb/apps
163-
RUN apt update -y && apt install -y chromium sqlite3
188+
RUN --mount=type=cache,target=/var/cache/apt,sharing=private,id=ubuntu2204-aptcache \
189+
--mount=type=cache,target=/var/lib/apt,sharing=private,id=ubuntu2204-aptlib \
190+
add-apt-repository -y ppa:xtradeb/apps;
191+
RUN --mount=type=cache,target=/var/cache/apt,sharing=private,id=ubuntu2204-aptcache \
192+
--mount=type=cache,target=/var/lib/apt,sharing=private,id=ubuntu2204-aptlib \
193+
apt update -y && \
194+
apt -y install chromium && \
195+
apt --no-install-recommends -y install sqlite3;
164196

165197
# install Node.js 22.x by copying from the node:22-bullseye-slim stage
166198
COPY --from=node-22 /usr/local/bin/node /usr/local/bin/node
@@ -174,7 +206,7 @@ RUN set -eux; \
174206
fi
175207

176208
# Install TypeScript and Playwright globally
177-
RUN npm install -g typescript playwright-core tsx
209+
RUN --mount=type=cache,target=/root/.npm npm install -g typescript playwright-core tsx
178210

179211
# setup desktop env & app
180212
ENV DISPLAY_NUM=1

images/chromium-headful/client/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ WORKDIR /src
66
#
77
# install dependencies
88
COPY package*.json ./
9-
RUN npm install
9+
RUN --mount=type=cache,target=/root/.npm npm install
1010

1111
#
1212
# build client
1313
COPY . .
14-
RUN npm run build
14+
RUN --mount=type=cache,target=/root/.npm npm run build
1515

1616
#
1717
# artifacts from this stage

images/chromium-headful/xorg-deps/Dockerfile

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ FROM $BASE_IMAGE AS xorg-deps
44
WORKDIR /xorg
55

66
ENV DEBIAN_FRONTEND=noninteractive
7-
RUN set -eux; \
7+
RUN --mount=type=cache,target=/var/cache/apt,sharing=private,id=ubuntu2204-aptcache \
8+
--mount=type=cache,target=/var/lib/apt,sharing=private,id=ubuntu2204-aptlib \
9+
rm -f /etc/apt/apt.conf.d/docker-clean; \
10+
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache; \
11+
set -eux; \
812
apt-get update; \
9-
apt-get install -y \
10-
git gcc pkgconf autoconf automake libtool make xorg-dev xutils-dev \
11-
&& rm -rf /var/lib/apt/lists/*;
13+
apt-get --no-install-recommends -y install \
14+
git gcc pkgconf autoconf automake libtool make xorg-dev xutils-dev;
15+
1216

1317
COPY . /xorg/
1418

images/chromium-headful/xorg-deps/xf86-input-neko/Dockerfile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ FROM debian:bullseye-slim
22

33
ENV DEBIAN_FRONTEND=noninteractive
44

5-
RUN set -eux; \
5+
RUN --mount=type=cache,target=/var/cache/apt,sharing=private,id=debian-bullseye-aptcache \
6+
--mount=type=cache,target=/var/lib/apt,sharing=private,id=debian-bullseye-aptlib \
7+
rm -f /etc/apt/apt.conf.d/docker-clean; \
8+
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache; \
9+
set -eux; \
610
apt-get update; \
7-
apt-get install -y \
8-
gcc pkgconf autoconf automake libtool make xorg-dev xutils-dev \
9-
&& rm -rf /var/lib/apt/lists/*;
11+
apt-get install --no-install-recommends -y \
12+
gcc pkgconf autoconf automake libtool make xorg-dev xutils-dev;
1013

1114
WORKDIR /app
1215

images/chromium-headless/image/Dockerfile

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,16 @@ ENV CGO_ENABLED=0
99
# Go module dependencies first for better layer caching
1010
COPY server/go.mod ./
1111
COPY server/go.sum ./
12-
RUN go mod download
12+
RUN --mount=type=cache,target=/root/.cache/go-build \
13+
--mount=type=cache,target=/go/pkg/mod \
14+
go mod download
1315

1416
COPY server/ .
1517

1618
# Build kernel-images API
17-
RUN GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} \
19+
RUN --mount=type=cache,target=/root/.cache/go-build \
20+
--mount=type=cache,target=/go/pkg/mod \
21+
GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} \
1822
go build -ldflags="-s -w" -o /out/kernel-images-api ./cmd/api
1923

2024
# Build chromium launcher
@@ -23,10 +27,13 @@ RUN GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} \
2327

2428
FROM node:22-bullseye-slim AS node-22
2529
FROM docker.io/ubuntu:22.04
26-
27-
RUN set -xe; \
30+
RUN --mount=type=cache,target=/var/cache/apt,sharing=private,id=ubuntu2204-aptcache \
31+
--mount=type=cache,target=/var/lib/apt,sharing=private,id=ubuntu2204-aptlib \
32+
rm -f /etc/apt/apt.conf.d/docker-clean; \
33+
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache; \
34+
set -xe; \
2835
apt-get -yqq update; \
29-
apt-get -yqq install \
36+
apt-get -yqq --no-install-recommends install \
3037
libcups2 \
3138
libnss3 \
3239
libatk1.0-0 \
@@ -43,12 +50,13 @@ RUN set -xe; \
4350
libxrandr2 \
4451
libgbm1 \
4552
libnss3; \
46-
apt-get -yqq install \
53+
apt-get -yqq --no-install-recommends install \
4754
ca-certificates \
4855
curl \
4956
build-essential \
5057
libssl-dev \
5158
git \
59+
gpg-agent \
5260
dbus \
5361
dbus-x11 \
5462
xvfb \
@@ -58,21 +66,51 @@ RUN set -xe; \
5866
supervisor;
5967

6068
# install chromium and sqlite3 for debugging the cookies file
61-
RUN add-apt-repository -y ppa:xtradeb/apps
62-
RUN apt update -y && apt install -y chromium sqlite3
69+
RUN --mount=type=cache,target=/var/cache/apt,sharing=private,id=ubuntu2204-aptcache \
70+
--mount=type=cache,target=/var/lib/apt,sharing=private,id=ubuntu2204-aptlib \
71+
add-apt-repository -y ppa:xtradeb/apps
72+
RUN --mount=type=cache,target=/var/cache/apt,sharing=private,id=ubuntu2204-aptcache \
73+
--mount=type=cache,target=/var/lib/apt,sharing=private,id=ubuntu2204-aptlib \
74+
apt-get update -y && \
75+
apt-get -y install chromium && \
76+
apt-get --no-install-recommends -y install sqlite3;
6377

6478
# Install FFmpeg (latest static build) for the recording server
65-
RUN set -eux; \
66-
URL="https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz"; \
67-
echo "Downloading FFmpeg static build from $URL"; \
68-
curl -fsSL "$URL" -o /tmp/ffmpeg.tar.xz; \
69-
tar -xJf /tmp/ffmpeg.tar.xz -C /tmp; \
70-
install -m755 /tmp/ffmpeg-*/ffmpeg /usr/local/bin/ffmpeg; \
71-
install -m755 /tmp/ffmpeg-*/ffprobe /usr/local/bin/ffprobe; \
79+
RUN --mount=type=cache,target=/tmp/cache/ffmpeg,id=ffmpeg \
80+
<<-'EOT'
81+
set -eux
82+
URL="https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz"
83+
echo "Downloading FFmpeg MD5 checksum"
84+
if ! curl --connect-timeout 10 -fsSL "${URL}.md5" -o /tmp/cache/ffmpeg/ffmpeg.tar.xz.md5; then
85+
echo "Failed to connect to ffmpeg static build provider for MD5 checksum."
86+
echo "Checking for cached version to use."
87+
if [ ! -f /tmp/cache/ffmpeg/ffmpeg.tar.xz.md5 ]; then
88+
echo "Unable to locate cached MD5 checksum. Exiting."
89+
exit 1
90+
else
91+
echo "Found cached MD5 checksum."
92+
fi
93+
fi
94+
sed -i -e 's/ .*$/ \/tmp\/cache\/ffmpeg\/ffmpeg.tar.xz/' /tmp/cache/ffmpeg/ffmpeg.tar.xz.md5
95+
echo "Checking cache for FFmpeg archive and validating MD5 checksum"
96+
if md5sum --check /tmp/cache/ffmpeg/ffmpeg.tar.xz.md5; then
97+
echo "Checksum validated, using cached FFmpeg archive"
98+
else
99+
echo "Downloading FFmpeg static build from $URL"
100+
curl -fsSL "$URL" -o /tmp/cache/ffmpeg/ffmpeg.tar.xz
101+
echo "Validating MD5 checksum of FFmpeg static build download"
102+
md5sum --check /tmp/cache/ffmpeg/ffmpeg.tar.xz.md5
103+
fi
104+
tar -xJf /tmp/cache/ffmpeg/ffmpeg.tar.xz -C /tmp
105+
install -m755 /tmp/ffmpeg-*/ffmpeg /usr/local/bin/ffmpeg
106+
install -m755 /tmp/ffmpeg-*/ffprobe /usr/local/bin/ffprobe
72107
rm -rf /tmp/ffmpeg*
108+
EOT
73109

74110
# Remove upower to prevent spurious D-Bus activations and logs
75-
RUN apt-get -yqq purge upower || true && rm -rf /var/lib/apt/lists/*
111+
RUN --mount=type=cache,target=/var/cache/apt,sharing=private,id=ubuntu2204-aptcache \
112+
--mount=type=cache,target=/var/lib/apt,sharing=private,id=ubuntu2204-aptlib \
113+
apt-get -yqq purge upower || true
76114

77115
# install Node.js 22.x by copying from the node:22-bullseye-slim stage
78116
COPY --from=node-22 /usr/local/bin/node /usr/local/bin/node

0 commit comments

Comments
 (0)