🐳 Migrate imagemagick and devenv images to DHI

Move docker/imagemagick/Dockerfile and docker/devenv/Dockerfile from
ubuntu:26.04 to Docker Hardened Images (Debian 13 / trixie).
imagemagick gets a true non-dev runtime with its shared libraries
vendored via ldd; devenv keeps the -dev tag as its final image since
it's an interactive development container, not a production
artifact.
This commit is contained in:
David Barragán Merino 2026-07-16 15:45:32 +02:00 committed by Andrey Antukh
parent 863671135d
commit 328fa0559a
4 changed files with 95 additions and 47 deletions

View File

@ -20,12 +20,19 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Login to Docker Registry
- name: Login to Docker Registry (push destination)
uses: docker/login-action@v4
with:
username: ${{ secrets.PUB_DOCKER_USERNAME }}
password: ${{ secrets.PUB_DOCKER_PASSWORD }}
- name: Login to Docker Hardened Images registry (base image pull)
uses: docker/login-action@v4
with:
registry: dhi.io
username: ${{ secrets.PUB_DOCKER_USERNAME }}
password: ${{ secrets.PUB_DOCKER_PASSWORD }}
- name: Build and push DevEnv Docker image
uses: docker/build-push-action@v7
env:
@ -35,6 +42,8 @@ jobs:
file: ./docker/devenv/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
provenance: mode=max
sbom: true
tags: ${{ env.DOCKER_IMAGE }}:latest
cache-from: type=registry,ref=${{ env.DOCKER_IMAGE }}:buildcache
cache-to: type=registry,ref=${{ env.DOCKER_IMAGE }}:buildcache,mode=max

View File

@ -1,4 +1,4 @@
FROM ubuntu:26.04 AS base
FROM dhi.io/debian-base:trixie-debian13-dev AS base
ENV LANG='C.UTF-8' \
LC_ALL='C.UTF-8' \
@ -13,6 +13,8 @@ RUN set -ex; \
rsync \
wget \
sudo \
libpam-modules \
libpam-runtime \
tmux \
vim \
curl \
@ -24,7 +26,39 @@ RUN set -ex; \
ca-certificates \
\
binutils \
build-essential autoconf libtool pkg-config
build-essential autoconf libtool pkg-config \
; \
mkdir -p /usr/lib/pam.d; \
printf '%s\n' \
'#%PAM-1.0' \
'auth required pam_unix.so nullok' \
'account required pam_unix.so' \
'password required pam_unix.so' \
'session required pam_unix.so' \
'session required pam_limits.so' \
| tee /etc/pam.d/sudo /usr/lib/pam.d/sudo > /dev/null; \
printf '%s\n' \
'#%PAM-1.0' \
'auth required pam_deny.so' \
'account required pam_deny.so' \
'password required pam_deny.so' \
'session required pam_deny.so' \
| tee /etc/pam.d/other /usr/lib/pam.d/other > /dev/null; \
if [ ! -s /etc/nsswitch.conf ]; then \
printf '%s\n' \
'passwd: files' \
'group: files' \
'shadow: files' \
'gshadow: files' \
'hosts: files dns' \
'networks: files' \
'protocols: files' \
'services: files' \
'ethers: files' \
'rpc: files' \
'netgroup: files' \
> /etc/nsswitch.conf; \
fi
################################################################################
## NODE SETUP
@ -374,13 +408,17 @@ RUN set -ex; \
FROM base AS devenv-base
RUN set -ex; \
usermod -l penpot -d /home/penpot -G users -s /bin/bash ubuntu; \
apt-get -qq update; \
apt-get -qqy --no-install-recommends install passwd; \
groupadd -f users; \
useradd -u 1000 -m -d /home/penpot -G users -s /bin/bash penpot; \
passwd penpot -d; \
echo "penpot ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
RUN set -ex; \
apt-get -qq update; \
apt-get -qq dist-upgrade; \
apt-get -qqy --no-install-recommends install init-system-helpers; \
apt-get -qqy install --no-install-recommends \
redis-tools \
gnupg2 \
@ -414,16 +452,16 @@ RUN set -ex; \
fonts-freefont-ttf \
poppler-utils \
\
libasound2t64 \
libatk-bridge2.0-0t64 \
libatk1.0-0t64 \
libatspi2.0-0t64 \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libatspi2.0-0 \
libcairo2 \
libcups2t64 \
libcups2 \
libdbus-1-3 \
libdrm2 \
libgbm1 \
libglib2.0-0t64 \
libglib2.0-0 \
libnspr4 \
libnss3 \
libpango-1.0-0 \
@ -437,14 +475,14 @@ RUN set -ex; \
libxrandr2 \
\
libpng16-16 \
libjpeg-turbo8 \
libjpeg62-turbo \
libtiff6 \
libwebp7 \
libopenexr-3-1-30 \
libfreetype6 \
libfontconfig1 \
libglib2.0-0 \
libxml2-16 \
libxml2 \
liblcms2-2 \
libheif1 \
libopenjp2-7 \
@ -455,12 +493,15 @@ RUN set -ex; \
libwebpdemux2 \
libzip5 \
; \
rm -rf /var/lib/apt/lists/*;
rm -rf /var/lib/apt/lists/*; \
mkdir -p /usr/local/bin; \
ln -sf /usr/bin/fdfind /usr/local/bin/fd; \
ln -sf /usr/bin/batcat /usr/local/bin/bat;
RUN set -ex; \
install -d /usr/share/postgresql-common/pgdg; \
curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc; \
echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt noble-pgdg main" >> /etc/apt/sources.list.d/postgresql.list; \
echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt trixie-pgdg main" >> /etc/apt/sources.list.d/postgresql.list; \
apt-get -qq update; \
apt-get -qqy install postgresql-client-16; \
apt-get clean; \
@ -487,7 +528,7 @@ ENV LANG='C.UTF-8' \
SERENA_CONTEXT="claude-code" \
PATH="/opt/jdk/bin:/opt/gh/bin:/opt/utils/bin:/opt/clojure/bin:/opt/node/bin:/opt/imagick/bin:/opt/cargo/bin:$PATH"
COPY --from=penpotapp/imagemagick:7.1.2-24 /opt/imagick /opt/imagick
COPY --from=penpotapp/imagemagick:7.1.2-27 /opt/imagick /opt/imagick
COPY --from=setup-jvm /opt/jdk /opt/jdk
COPY --from=setup-jvm /opt/clojure /opt/clojure
COPY --from=setup-node /opt/node /opt/node
@ -519,3 +560,4 @@ COPY files/init.sh /home/init.sh
ENTRYPOINT ["/home/entrypoint.sh"]
CMD ["/home/init.sh"]

View File

@ -19,7 +19,7 @@ chown -R penpot:users ${SERENA_HOME}
chown penpot:users /home/penpot
# we need to be able to install rust-analyzer and possibly other dependencies with rustup
chown -R penpot:ubuntu /opt/rustup
chown -R penpot:penpot /opt/rustup
rsync -ar --chown=penpot:users /opt/cargo/ /home/penpot/.cargo/

View File

@ -1,4 +1,4 @@
FROM ubuntu:26.04
FROM dhi.io/debian-base:trixie-debian13-dev AS build
LABEL maintainer="Penpot <docker@penpot.app>"
ENV LANG='C.UTF-8' \
@ -6,11 +6,12 @@ ENV LANG='C.UTF-8' \
DEBIAN_FRONTEND=noninteractive \
TZ=Etc/UTC
ARG IMAGEMAGICK_VERSION=7.1.2-24
ARG IMAGEMAGICK_VERSION=7.1.2-27
RUN set -e; \
apt-get -qq update; \
apt-get -qq upgrade; \
apt-get -qqy --no-install-recommends install init-system-helpers; \
apt-get -qqy --no-install-recommends install \
autoconf \
binutils \
@ -38,42 +39,24 @@ RUN set -e; \
mkdir -p /tmp/magick; \
cd /tmp/magick; \
tar -xf /tmp/magick.tar.gz --strip-components=1; \
./configure --prefix=/opt/imagick; \
./configure --prefix=/opt/imagick; \
make -j 2; \
make install; \
rm -rf /opt/imagick/lib/libMagick++*; \
rm -rf /opt/imagick/include; \
rm -rf /opt/imagick/share; \
apt-get -qqy --autoremove purge \
autoconf \
binutils \
build-essential \
ca-certificates \
curl \
libfftw3-dev \
libheif-dev \
libjpeg-dev \
libxml2-dev \
liblcms2-dev \
libltdl-dev \
liblzma-dev \
libopenexr-dev \
libpng-dev \
librsvg2-dev \
libtiff-dev \
libtool\
libwebp-dev \
libzip-dev \
libzstd-dev \
pkg-config \
;\
rm -rf /opt/imagick/share;
# The DHI runtime image ships no apt/dpkg, so `magick`'s ~15 runtime shared
# libs (libheif, libopenjp2, librsvg2, etc.) are vendored here via `ldd` into
# a self-contained bundle instead of relying on system packages at runtime.
RUN set -ex; \
apt-get -qqy --no-install-recommends install \
libfontconfig1 \
libfreetype6 \
libglib2.0-0 \
libgomp1 \
libheif1 \
libjpeg-turbo8 \
libjpeg62-turbo \
liblcms2-2 \
libopenexr-3-1-30 \
libopenjp2-7 \
@ -83,11 +66,25 @@ RUN set -e; \
libwebp7 \
libwebpdemux2 \
libwebpmux3 \
libxml2-16 \
libxml2 \
libzip5 \
libzstd1 \
;\
; \
mkdir -p /opt/imagick/lib/deps; \
ldd /opt/imagick/bin/magick | awk '{print $3}' | grep '^/' | sort -u \
| xargs -I{} cp -L --no-clobber {} /opt/imagick/lib/deps/; \
apt-get -qqy clean; \
rm -rf /var/lib/apt/lists/*;
rm -rf /var/lib/apt/lists/*
FROM dhi.io/debian-base:trixie-debian13 AS image
LABEL maintainer="Penpot <docker@penpot.app>"
ENV LANG='C.UTF-8' \
LC_ALL='C.UTF-8' \
TZ=Etc/UTC \
LD_LIBRARY_PATH=/opt/imagick/lib/deps
COPY --from=build /opt/imagick /opt/imagick
ENTRYPOINT ["/opt/imagick/bin/magick"]