docker: static libdbus + disable Qt glib to shed the viewer's .so tail

The jfjoch_viewer runtime pulled a large dynamic .so tail that traces to two
Qt-side integrations, neither of which the viewer actually needs:

- Qt6::DBus -> system libdbus-1.so -> libsystemd (libzstd/liblz4/libcap/
  libgcrypt/libgpg-error) + libselinux (libpcre2). The viewer is a pure
  session-bus client (registers ch.psi.jfjoch_viewer + exports an adaptor for
  single-instance/remote-control), so the daemon-side systemd/selinux features
  are irrelevant. Build a static libdbus from source with those integrations
  disabled and link it into the viewer, the same from-source-static pattern
  already used for OpenSSL. Swap the dbus dev package for expat (dbus's
  configure-time dep; the client libdbus-1 links neither expat nor systemd) so
  nothing pulls the system shared dbus back in.

  Qt discovers dbus through find_package(DBus1) (its FindWrapDBus1.cmake), NOT
  pkg-config -- so point it at our build with -DDBus1_DIR=<prefix>/lib/cmake/
  DBus1 (the CMake package config dbus installs, which imports libdbus-1.a) and
  force QT_FEATURE_dbus_linked=ON so QtDBus links the archive instead of
  dlopen'ing a (now nonexistent) libdbus-1.so.3 at runtime.

- Qt's glib event-dispatcher -> libglib-2.0/libgthread/libpcre. Nothing in the
  viewer (or any lib it links) drives a GLib main context, so switch Qt to its
  own QEventDispatcherUNIX via QT_FEATURE_glib=OFF and drop the glib dev package.

Applied identically across rocky8, rocky9, ubuntu2204, ubuntu2404.

Note: system libcrypto still appears at runtime, but it is dragged in by the
dynamic system krb5/GSSAPI (built against OpenSSL on RHEL/Rocky), which we keep
dynamic for the planned httpd-reverse-proxy Kerberos auth -- not from Qt or curl,
which both statically link the from-source OpenSSL.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-13 15:35:43 +02:00
co-authored by Claude Opus 4.8
parent dd0bffb283
commit 5baf2a2cac
4 changed files with 128 additions and 8 deletions
+32 -2
View File
@@ -3,6 +3,7 @@ LABEL authors="leonarski_f"
ARG OPENSSL_VERSION=3.5.4
ARG QT_VERSION=6.9.1
ARG DBUS_VERSION=1.14.10
ARG NODE_MAJOR=22
ARG EIGEN_VERSION=3.4.0
# HDF5, libtiff and libjpeg-turbo are built by the jungfraujoch CMake itself (FetchContent /
@@ -47,11 +48,10 @@ RUN dnf -y install epel-release && \
libXinerama-devel \
mesa-libGL-devel \
mesa-libEGL-devel \
dbus-devel \
expat-devel \
krb5-devel \
zlib-devel \
zlib-static \
glib2-devel \
fontconfig-devel \
zlib-static \
java-21-openjdk-headless \
@@ -96,6 +96,33 @@ ENV CXX=${GCC_TOOLSET_ROOT}/usr/bin/g++
ENV PKG_CONFIG_PATH=${OPENSSL_ROOT_DIR}/lib/pkgconfig:${OPENSSL_ROOT_DIR}/lib64/pkgconfig
# Static libdbus: link D-Bus into the viewer (Qt6::DBus) instead of pulling libdbus-1.so.3 at runtime.
# A distro libdbus-1.so drags in libsystemd (-> libzstd/liblz4/libcap/libgcrypt/libgpg-error) and
# libselinux (-> libpcre2). Disabling those integrations makes libdbus-1.a depend on ~libc alone, so
# that whole runtime .so tail disappears while the viewer keeps its single-instance / remote-control
# D-Bus feature -- it is a pure session-bus client (registers a name + exports an adaptor), so the
# daemon-side systemd/selinux features are irrelevant. Static-only install (no .so); the Qt build
# finds it through find_package(DBus1) via the -DDBus1_DIR hint (the CMake package config dbus
# installs, which imports libdbus-1.a). expat is only a configure-time dep of
# the dbus daemon; the client libdbus-1 links neither expat nor systemd.
RUN set -eux; \
cd /tmp; \
curl -LO https://dbus.freedesktop.org/releases/dbus/dbus-${DBUS_VERSION}.tar.xz; \
tar -xf dbus-${DBUS_VERSION}.tar.xz; \
cd dbus-${DBUS_VERSION}; \
./configure --prefix=/opt/dbus-${DBUS_VERSION}-static \
--enable-static --disable-shared \
--disable-systemd --without-systemdsystemunitdir \
--disable-selinux --disable-apparmor --disable-libaudit \
--disable-tests --disable-asserts \
--disable-doxygen-docs --disable-xml-docs --disable-ducktype-docs; \
make -j"$(nproc)"; \
make install; \
cd /; rm -rf /tmp/dbus-${DBUS_VERSION} /tmp/dbus-${DBUS_VERSION}.tar.xz
# Put the static libdbus pkgconfig ahead of the system one so Qt6::DBus resolves to the .a
ENV PKG_CONFIG_PATH=/opt/dbus-${DBUS_VERSION}-static/lib/pkgconfig:${PKG_CONFIG_PATH}
ARG QT_PREFIX=/opt/qt-${QT_VERSION}-static
RUN set -eux; \
cd /tmp; \
@@ -108,6 +135,8 @@ RUN set -eux; \
-DQT_BUILD_TESTS=OFF \
-DQT_BUILD_EXAMPLES=OFF \
-DQT_FEATURE_dbus=ON \
-DQT_FEATURE_dbus_linked=ON \
-DDBus1_DIR=/opt/dbus-${DBUS_VERSION}-static/lib/cmake/DBus1 \
-DQT_FEATURE_xcb=ON \
-DQT_FEATURE_xcb_xlib=OFF \
-DQT_FEATURE_xkbcommon_x11=ON \
@@ -115,6 +144,7 @@ RUN set -eux; \
-DQT_FEATURE_opengl_desktop=ON \
-DQT_FEATURE_opengl_dynamic=OFF \
-DQT_FEATURE_vulkan=OFF \
-DQT_FEATURE_glib=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=${QT_PREFIX} \
-DCMAKE_C_COMPILER=${CC} \
+32 -2
View File
@@ -3,6 +3,7 @@ LABEL authors="leonarski_f"
ARG OPENSSL_VERSION=3.5.4
ARG QT_VERSION=6.9.1
ARG DBUS_VERSION=1.14.10
ARG NODE_MAJOR=22
ARG EIGEN_VERSION=3.4.0
# HDF5, libtiff and libjpeg-turbo are built by the jungfraujoch CMake itself (FetchContent /
@@ -57,11 +58,10 @@ RUN dnf -y update && \
libXinerama-devel \
mesa-libGL-devel \
mesa-libEGL-devel \
dbus-devel \
expat-devel \
krb5-devel \
zlib-devel \
zlib-static \
glib2-devel \
zlib-static \
fontconfig-devel \
mesa-dri-drivers \
@@ -99,6 +99,33 @@ ENV PATH=${GCC_TOOLSET_ROOT}/usr/bin:${PATH}
ENV CC=${GCC_TOOLSET_ROOT}/usr/bin/gcc
ENV CXX=${GCC_TOOLSET_ROOT}/usr/bin/g++
# Static libdbus: link D-Bus into the viewer (Qt6::DBus) instead of pulling libdbus-1.so.3 at runtime.
# A distro libdbus-1.so drags in libsystemd (-> libzstd/liblz4/libcap/libgcrypt/libgpg-error) and
# libselinux (-> libpcre2). Disabling those integrations makes libdbus-1.a depend on ~libc alone, so
# that whole runtime .so tail disappears while the viewer keeps its single-instance / remote-control
# D-Bus feature -- it is a pure session-bus client (registers a name + exports an adaptor), so the
# daemon-side systemd/selinux features are irrelevant. Static-only install (no .so); the Qt build
# finds it through find_package(DBus1) via the -DDBus1_DIR hint (the CMake package config dbus
# installs, which imports libdbus-1.a). expat is only a configure-time dep of
# the dbus daemon; the client libdbus-1 links neither expat nor systemd.
RUN set -eux; \
cd /tmp; \
curl -LO https://dbus.freedesktop.org/releases/dbus/dbus-${DBUS_VERSION}.tar.xz; \
tar -xf dbus-${DBUS_VERSION}.tar.xz; \
cd dbus-${DBUS_VERSION}; \
./configure --prefix=/opt/dbus-${DBUS_VERSION}-static \
--enable-static --disable-shared \
--disable-systemd --without-systemdsystemunitdir \
--disable-selinux --disable-apparmor --disable-libaudit \
--disable-tests --disable-asserts \
--disable-doxygen-docs --disable-xml-docs --disable-ducktype-docs; \
make -j"$(nproc)"; \
make install; \
cd /; rm -rf /tmp/dbus-${DBUS_VERSION} /tmp/dbus-${DBUS_VERSION}.tar.xz
# Put the static libdbus pkgconfig ahead of the system one so Qt6::DBus resolves to the .a
ENV PKG_CONFIG_PATH=/opt/dbus-${DBUS_VERSION}-static/lib/pkgconfig:${PKG_CONFIG_PATH}
# Build and install static Qt 6.9 with Core, Gui, Widgets, Charts, DBus
ARG QT_PREFIX=/opt/qt-${QT_VERSION}-static
RUN set -eux; \
@@ -112,6 +139,8 @@ RUN set -eux; \
-DQT_BUILD_TESTS=OFF \
-DQT_BUILD_EXAMPLES=OFF \
-DQT_FEATURE_dbus=ON \
-DQT_FEATURE_dbus_linked=ON \
-DDBus1_DIR=/opt/dbus-${DBUS_VERSION}-static/lib/cmake/DBus1 \
-DQT_FEATURE_xcb=ON \
-DQT_FEATURE_xcb_xlib=OFF \
-DQT_FEATURE_xkbcommon_x11=ON \
@@ -119,6 +148,7 @@ RUN set -eux; \
-DQT_FEATURE_opengl_desktop=ON \
-DQT_FEATURE_opengl_dynamic=OFF \
-DQT_FEATURE_vulkan=OFF \
-DQT_FEATURE_glib=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=${QT_PREFIX} \
-DCMAKE_C_COMPILER=${CC} \
+32 -2
View File
@@ -6,6 +6,7 @@ ENV DEBIAN_FRONTEND=noninteractive
ARG OPENSSL_VERSION=3.5.4
ARG QT_VERSION=6.9.1
ARG DBUS_VERSION=1.14.10
ARG NODE_MAJOR=22
ARG EIGEN_VERSION=3.4.0
# HDF5, libtiff and libjpeg-turbo are built by the jungfraujoch CMake itself (FetchContent /
@@ -71,9 +72,8 @@ RUN set -eux; \
libgl1-mesa-dev \
libglx-dev \
libegl1-mesa-dev \
libdbus-1-dev \
libexpat1-dev \
zlib1g-dev \
libglib2.0-dev \
libfontconfig1-dev \
libdrm-dev \
mesa-utils \
@@ -123,6 +123,33 @@ RUN set -eux; \
rm -rf /var/lib/apt/lists/*; \
node --version; npm --version; (corepack enable || true)
# Static libdbus: link D-Bus into the viewer (Qt6::DBus) instead of pulling libdbus-1.so.3 at runtime.
# A distro libdbus-1.so drags in libsystemd (-> libzstd/liblz4/libcap/libgcrypt/libgpg-error) and
# libselinux (-> libpcre2). Disabling those integrations makes libdbus-1.a depend on ~libc alone, so
# that whole runtime .so tail disappears while the viewer keeps its single-instance / remote-control
# D-Bus feature -- it is a pure session-bus client (registers a name + exports an adaptor), so the
# daemon-side systemd/selinux features are irrelevant. Static-only install (no .so); the Qt build
# finds it through find_package(DBus1) via the -DDBus1_DIR hint (the CMake package config dbus
# installs, which imports libdbus-1.a). expat is only a configure-time dep of
# the dbus daemon; the client libdbus-1 links neither expat nor systemd.
RUN set -eux; \
cd /tmp; \
curl -LO https://dbus.freedesktop.org/releases/dbus/dbus-${DBUS_VERSION}.tar.xz; \
tar -xf dbus-${DBUS_VERSION}.tar.xz; \
cd dbus-${DBUS_VERSION}; \
./configure --prefix=/opt/dbus-${DBUS_VERSION}-static \
--enable-static --disable-shared \
--disable-systemd --without-systemdsystemunitdir \
--disable-selinux --disable-apparmor --disable-libaudit \
--disable-tests --disable-asserts \
--disable-doxygen-docs --disable-xml-docs --disable-ducktype-docs; \
make -j"$(nproc)"; \
make install; \
cd /; rm -rf /tmp/dbus-${DBUS_VERSION} /tmp/dbus-${DBUS_VERSION}.tar.xz
# Put the static libdbus pkgconfig ahead of the system one so Qt6::DBus resolves to the .a
ENV PKG_CONFIG_PATH=/opt/dbus-${DBUS_VERSION}-static/lib/pkgconfig:${PKG_CONFIG_PATH}
# Build and install static Qt with Core, Gui, Widgets, Charts, DBus
ARG QT_PREFIX=/opt/qt-${QT_VERSION}-static
RUN set -eux; \
@@ -136,6 +163,8 @@ RUN set -eux; \
-DQT_BUILD_TESTS=OFF \
-DQT_BUILD_EXAMPLES=OFF \
-DQT_FEATURE_dbus=ON \
-DQT_FEATURE_dbus_linked=ON \
-DDBus1_DIR=/opt/dbus-${DBUS_VERSION}-static/lib/cmake/DBus1 \
-DQT_FEATURE_xcb=ON \
-DQT_FEATURE_xcb_xlib=OFF \
-DQT_FEATURE_xkbcommon_x11=ON \
@@ -143,6 +172,7 @@ RUN set -eux; \
-DQT_FEATURE_opengl_desktop=ON \
-DQT_FEATURE_opengl_dynamic=OFF \
-DQT_FEATURE_vulkan=OFF \
-DQT_FEATURE_glib=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=${QT_PREFIX} \
-DCMAKE_C_COMPILER=${CC} \
+32 -2
View File
@@ -6,6 +6,7 @@ ENV DEBIAN_FRONTEND=noninteractive
ARG OPENSSL_VERSION=3.5.4
ARG QT_VERSION=6.9.1
ARG DBUS_VERSION=1.14.10
ARG NODE_MAJOR=22
ARG EIGEN_VERSION=3.4.0
# HDF5, libtiff and libjpeg-turbo are built by the jungfraujoch CMake itself (FetchContent /
@@ -71,9 +72,8 @@ RUN set -eux; \
libgl1-mesa-dev \
libglx-dev \
libegl1-mesa-dev \
libdbus-1-dev \
libexpat1-dev \
zlib1g-dev \
libglib2.0-dev \
libfontconfig1-dev \
libdrm-dev \
libglvnd-dev \
@@ -110,6 +110,33 @@ RUN set -eux; \
rm -rf /var/lib/apt/lists/*; \
node --version; npm --version; (corepack enable || true)
# Static libdbus: link D-Bus into the viewer (Qt6::DBus) instead of pulling libdbus-1.so.3 at runtime.
# A distro libdbus-1.so drags in libsystemd (-> libzstd/liblz4/libcap/libgcrypt/libgpg-error) and
# libselinux (-> libpcre2). Disabling those integrations makes libdbus-1.a depend on ~libc alone, so
# that whole runtime .so tail disappears while the viewer keeps its single-instance / remote-control
# D-Bus feature -- it is a pure session-bus client (registers a name + exports an adaptor), so the
# daemon-side systemd/selinux features are irrelevant. Static-only install (no .so); the Qt build
# finds it through find_package(DBus1) via the -DDBus1_DIR hint (the CMake package config dbus
# installs, which imports libdbus-1.a). expat is only a configure-time dep of
# the dbus daemon; the client libdbus-1 links neither expat nor systemd.
RUN set -eux; \
cd /tmp; \
curl -LO https://dbus.freedesktop.org/releases/dbus/dbus-${DBUS_VERSION}.tar.xz; \
tar -xf dbus-${DBUS_VERSION}.tar.xz; \
cd dbus-${DBUS_VERSION}; \
./configure --prefix=/opt/dbus-${DBUS_VERSION}-static \
--enable-static --disable-shared \
--disable-systemd --without-systemdsystemunitdir \
--disable-selinux --disable-apparmor --disable-libaudit \
--disable-tests --disable-asserts \
--disable-doxygen-docs --disable-xml-docs --disable-ducktype-docs; \
make -j"$(nproc)"; \
make install; \
cd /; rm -rf /tmp/dbus-${DBUS_VERSION} /tmp/dbus-${DBUS_VERSION}.tar.xz
# Put the static libdbus pkgconfig ahead of the system one so Qt6::DBus resolves to the .a
ENV PKG_CONFIG_PATH=/opt/dbus-${DBUS_VERSION}-static/lib/pkgconfig:${PKG_CONFIG_PATH}
# Build and install static Qt with Core, Gui, Widgets, Charts, DBus
ARG QT_PREFIX=/opt/qt-${QT_VERSION}-static
RUN set -eux; \
@@ -123,6 +150,8 @@ RUN set -eux; \
-DQT_BUILD_TESTS=OFF \
-DQT_BUILD_EXAMPLES=OFF \
-DQT_FEATURE_dbus=ON \
-DQT_FEATURE_dbus_linked=ON \
-DDBus1_DIR=/opt/dbus-${DBUS_VERSION}-static/lib/cmake/DBus1 \
-DQT_FEATURE_xcb=ON \
-DQT_FEATURE_xcb_xlib=OFF \
-DQT_FEATURE_xkbcommon_x11=ON \
@@ -130,6 +159,7 @@ RUN set -eux; \
-DQT_FEATURE_opengl_desktop=ON \
-DQT_FEATURE_opengl_dynamic=OFF \
-DQT_FEATURE_vulkan=OFF \
-DQT_FEATURE_glib=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=${QT_PREFIX} \
-DCMAKE_C_COMPILER=${CC} \