From 266dc77536547b89a197c14f9e279304e71d2536 Mon Sep 17 00:00:00 2001
From: Jade Ellis <jade@ellis.link>
Date: Tue, 25 Feb 2025 04:16:08 +0000
Subject: [PATCH] build: Create daemon image from scratch (#3452)

---
 .dockerignore     |  1 +
 server/Dockerfile | 45 ++++++++++++++++++++++++++++++++++-----------
 2 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/.dockerignore b/.dockerignore
index 8953dc613..c7ee73855 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -10,3 +10,4 @@ kanidmd/sampledata
 Makefile
 target
 test.db
+Dockerfile
diff --git a/server/Dockerfile b/server/Dockerfile
index a2e916ce2..f34668967 100644
--- a/server/Dockerfile
+++ b/server/Dockerfile
@@ -54,20 +54,43 @@ RUN --mount=type=cache,id=cargo,target=/cargo \
         --release; \
     sccache -s
 
+# Find and copy dynamically linked libraries using ldd
+# caveat: this actually partially runs the binary, so it doesn't work for cross-compilation
+RUN <<EOF
+    mkdir -p /out/libs
+    mkdir -p /out/libs-root
+    ldd /usr/src/kanidm/target/release/kanidmd
+    ldd /usr/src/kanidm/target/release/kanidmd | grep -v 'linux-vdso.so' | awk '{print $(NF-1) " " $1}' | sort -u -k 1,1 | awk '{print "install", "-D", $1, (($2 ~ /^\//) ? "/out/libs-root" $2 : "/out/libs/" $2)}' | xargs -I {} sh -c {}
+    ls -Rla /out/libs
+    ls -Rla /out/libs-root
+EOF
+
 # ======================
 
-FROM repos
-RUN \
-    --mount=type=cache,id=zypp,target=/var/cache/zypp \
-    zypper install -y \
-        timezone \
-        openssl-3 \
-        sqlite3 \
-        pam
+FROM scratch
 
-COPY --from=builder /usr/src/kanidm/target/release/kanidmd /sbin/
-COPY --from=builder /usr/src/kanidm/server/core/static /hpkg
-RUN chmod +x /sbin/kanidmd
+WORKDIR /
+
+# Copy root certs for tls into image
+# You can also mount the certs from the host
+# --volume /etc/ssl/certs:/etc/ssl/certs:ro
+COPY --from=repos /etc/ssl/certs /etc/ssl/certs
+
+# Copy our build
+COPY --from=builder --chmod=0755 /usr/src/kanidm/target/release/kanidmd /sbin/
+# Web assets
+COPY --from=builder /usr/src/kanidm/server/core/static /hpkg/
+
+# Copy fixed-path dynamic libraries to their position
+COPY --from=builder /out/libs-root/ /
+COPY --from=builder /out/libs/ /lib/
+
+# Inform loader where to find libraries
+# This is necessary because opensuse searches for libraries in /lib64 or /lib depending on the architecture, but we don't know which one we're on.
+# Alternatively, we could symlink /lib64 to /lib, and /usr/lib64 to /usr/lib, etc.
+# We could always fix this by invoking the loader on the host (which works in a cross build it seems), but this is easier.
+# On debian, it always searches for libraries in /lib.
+ENV LD_LIBRARY_PATH=/lib
 
 WORKDIR /data