From ee7d11606a293b83aa990aaacb1dec9c1355e5b8 Mon Sep 17 00:00:00 2001 From: Peter Pathirana Date: Tue, 18 Aug 2026 21:31:41 +0000 Subject: [PATCH 1/3] refactor: drop python and other unnecessary deps from image + add required dependencies from homebrew --- images/homelab-workspace/Dockerfile | 44 ++++++----------------------- 1 file changed, 8 insertions(+), 36 deletions(-) diff --git a/images/homelab-workspace/Dockerfile b/images/homelab-workspace/Dockerfile index 3338b73c..75dbeea4 100644 --- a/images/homelab-workspace/Dockerfile +++ b/images/homelab-workspace/Dockerfile @@ -47,11 +47,7 @@ RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt-${TARGETARCH},sharing= --mount=type=tmpfs,target=/tmp \ --mount=type=tmpfs,target=/var/log \ --mount=type=tmpfs,target=/var/tmp \ - # need unminimized variants of tools in coder workspace image apt-get update && \ - DEBIAN_FRONTEND="noninteractive" apt-get install -yq --no-install-recommends man-db unminimize && \ - sed -i 's|xargs dpkg -S|xargs -r dpkg -S|g' /usr/bin/unminimize && \ - printf 'y\ny\n' | /usr/bin/unminimize && \ # install system packages needed within coder workspace image DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -yq \ apt-file \ @@ -64,6 +60,8 @@ RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt-${TARGETARCH},sharing= dnsutils \ file \ fontconfig \ + g++ \ + gcc \ gettext \ git \ htop \ @@ -71,11 +69,9 @@ RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt-${TARGETARCH},sharing= iotop \ iputils-ping \ iputils-tracepath \ - ldap-utils \ less \ libarchive-tools \ - libheif-dev \ - libraw-dev \ + libc6-dev \ lsof \ lz4 \ make \ @@ -83,16 +79,10 @@ RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt-${TARGETARCH},sharing= netcat-openbsd \ net-tools \ openssh-client \ - pipx \ pkg-config \ - postgresql-client \ procps \ psmisc \ pv \ - python-is-python3 \ - python3 \ - python3-pip \ - python3-venv \ rsync \ screen \ sshpass \ @@ -114,29 +104,11 @@ RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt-${TARGETARCH},sharing= find /usr -name __pycache__ -exec rm -rf {} + # Docker CLI only (no docker-ce/containerd.io) - this workspace pod is unprivileged by design and has no -# local dockerd; the CLI talks to a remote daemon over `DOCKER_HOST=ssh://...` (wired up by the Terraform -# template). A local docker group/sudo rule would authorize access to a local socket that doesn't exist -# here - don't add one. buildx/compose are client-side plugins, so a remote daemon doesn't provide them; -# the apt packages install to /usr/libexec/docker/cli-plugins, one of the docker CLI's default plugin -# search paths, so `docker buildx`/`docker compose` resolve without extra configuration. -# -# docker-buildx and docker-compose are UPX-compressed in place afterwards (measured: to ~30% of their -# installed size each). /usr/bin/docker itself is deliberately left uncompressed: UPX refuses to pack it -# ("CantPackException: bad e_shstrtab", reproduced on UPX 4.2.2 and 5.2.0) because, unlike the other two, -# it's dynamically-linked/PIE rather than statically linked; `strip`-ing it first works around that but -# also drops its debug symbols, a separate trade-off not applied here without being asked for. UPX comes -# from its own GitHub release rather than the `upx-ucl` apt package, so the tool and its dependency -# closure never land in this layer and the version tracks upstream rather than whatever Ubuntu froze; it -# is downloaded, used, and removed within this same RUN, into the tmpfs-mounted /tmp so it can't leave a -# trace even if the explicit cleanup below were ever dropped. No sha256 pin on that download: the HTTPS -# GET already authenticates via GitHub's TLS certificate, and a hand-computed checksum has no automated -# way to be recomputed on a Renovate-driven UPX_VERSION bump, so it would just go stale and turn the next -# bump into a guaranteed broken build - same reasoning (and same operator) as the docker-host VM's -# cloud-init in homelab-ops-kubernetes-experiments, which omits checksums on its own -# download.docker.com/github.com fetches for this exact reason. Compressing these apt-installed binaries -# in place means `dpkg -V` will report them as modified - that's expected, not corruption. UPX-packed -# binaries also decompress into memory on every exec, a small startup-time/RSS cost that's a non-issue for -# an interactively-invoked CLI. +# local dockerd; the CLI talks to a remote daemon over `DOCKER_HOST=ssh://...`. A local docker group/sudo +# rule would authorize access to a local socket that doesn't exist here - don't add one. buildx/compose +# are client-side plugins, so a remote daemon doesn't provide them; the apt packages install to +# /usr/libexec/docker/cli-plugins, one of the docker CLI's default plugin search paths, so `docker buildx`/ +# `docker compose` resolve without extra configuration. # renovate: datasource=github-releases depName=upx/upx ARG UPX_VERSION="5.2.0" RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt-${TARGETARCH},sharing=locked \ From e435c5dd3c21bf961565049718b376fe4a56207a Mon Sep 17 00:00:00 2001 From: Peter Pathirana Date: Tue, 18 Aug 2026 21:51:16 +0000 Subject: [PATCH 2/3] fix: drop iotop to get rid of python --- images/homelab-workspace/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/images/homelab-workspace/Dockerfile b/images/homelab-workspace/Dockerfile index 75dbeea4..52da8e24 100644 --- a/images/homelab-workspace/Dockerfile +++ b/images/homelab-workspace/Dockerfile @@ -66,7 +66,6 @@ RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt-${TARGETARCH},sharing= git \ htop \ inetutils-tools \ - iotop \ iputils-ping \ iputils-tracepath \ less \ From acd15cd530b96505236e7a6e4aca0ff60564a9db Mon Sep 17 00:00:00 2001 From: Peter Pathirana Date: Tue, 18 Aug 2026 22:02:14 +0000 Subject: [PATCH 3/3] fix: drop unnecessary pycache config at apt doesn't use python --- images/homelab-workspace/Dockerfile | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/images/homelab-workspace/Dockerfile b/images/homelab-workspace/Dockerfile index 52da8e24..32affd0f 100644 --- a/images/homelab-workspace/Dockerfile +++ b/images/homelab-workspace/Dockerfile @@ -2,14 +2,9 @@ FROM ubuntu:resolute@sha256:678c6550cc43645e08669028bc177f50be4e7c5b8cca677067b1 SHELL ["/bin/bash", "-o", "pipefail", "-c"] ARG TARGETARCH -# Place all __pycache__ and *.pyc within a location outside of /usr or /opt, -# - so that it can be easily cleared by the user (as needed) -# - so that they need not be built into the image -ENV PYTHONPYCACHEPREFIX=/var/cache/python RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt-${TARGETARCH},sharing=locked \ --mount=type=cache,target=/var/cache/debconf,id=cache-debconf-${TARGETARCH},sharing=locked \ --mount=type=cache,target=/var/lib/apt,id=lib-apt-${TARGETARCH},sharing=locked \ - --mount=type=tmpfs,target=/var/cache/python \ --mount=type=tmpfs,target=/tmp \ --mount=type=tmpfs,target=/var/log \ # enable caching of apt packages @@ -30,20 +25,16 @@ RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt-${TARGETARCH},sharing= # generate locales (needed for many applications, specially python) echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && \ echo "LANG=en_US.UTF-8" > /etc/locale.conf && \ - LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 locale-gen en_US.UTF-8 && \ - # Clean pycache created during apt-get install (as apt stills retains some crud in spite of PYTHONPYCACHEPREFIX) - find /usr -name __pycache__ -exec rm -rf {} + + LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 locale-gen en_US.UTF-8 # ======================================================================================================== FROM base AS system-base SHELL ["/bin/bash", "-o", "pipefail", "-c"] ARG TARGETARCH -ENV PYTHONPYCACHEPREFIX=/var/cache/python RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt-${TARGETARCH},sharing=locked \ --mount=type=cache,target=/var/cache/debconf,id=cache-debconf-${TARGETARCH},sharing=locked \ --mount=type=cache,target=/var/lib/apt,id=lib-apt-${TARGETARCH},sharing=locked \ - --mount=type=tmpfs,target=/var/cache/python \ --mount=type=tmpfs,target=/tmp \ --mount=type=tmpfs,target=/var/log \ --mount=type=tmpfs,target=/var/tmp \ @@ -97,10 +88,7 @@ RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt-${TARGETARCH},sharing= wget \ xz-utils \ zip \ - zstd \ - && \ - # Clean pycache created during apt-get install (as apt stills retains some crud in spite of PYTHONPYCACHEPREFIX) - find /usr -name __pycache__ -exec rm -rf {} + + zstd # Docker CLI only (no docker-ce/containerd.io) - this workspace pod is unprivileged by design and has no # local dockerd; the CLI talks to a remote daemon over `DOCKER_HOST=ssh://...`. A local docker group/sudo @@ -131,8 +119,7 @@ RUN --mount=type=cache,target=/var/cache/apt,id=cache-apt-${TARGETARCH},sharing= "/tmp/upx-${UPX_VERSION}-${TARGETARCH}_linux/upx" -q \ /usr/libexec/docker/cli-plugins/docker-buildx \ /usr/libexec/docker/cli-plugins/docker-compose && \ - rm -rf "/tmp/upx.tar.xz" "/tmp/upx-${UPX_VERSION}-${TARGETARCH}_linux" && \ - find /usr -name __pycache__ -exec rm -rf {} + + rm -rf "/tmp/upx.tar.xz" "/tmp/upx-${UPX_VERSION}-${TARGETARCH}_linux" # ======================================================================================================== FROM system-base @@ -143,9 +130,12 @@ WORKDIR /tmp # Instead of utilizing ENV statements, we make use of /etc/environment file to make the requisite # environment variables available to all users of this image (primarily 'root' and 'coder') # - set starting PATH variable value (this strips some Ubuntu defaults such as games and snap directories) -# - Make typing unicode characters in the terminal work (w/ LC_ALL + LANG). RUN echo 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' > /etc/environment && \ + # Place all __pycache__ and *.pyc within a location outside of /usr or /opt, + # - so that it can be easily cleared by the user (as needed) + # - so that they need not be built into the image echo 'PYTHONPYCACHEPREFIX=/var/cache/python' >> /etc/environment && \ + # - Make typing unicode characters in the terminal work (w/ LC_ALL + LANG). echo 'LC_ALL=en_US.UTF-8' >> /etc/environment && \ echo 'LANG=en_US.UTF-8' >> /etc/environment && \ # This image has no dbus session bus and never will (no session manager, no systemd --user). Without