From 028570ff1792a6cdfd50b2d8de53274ed34bebac Mon Sep 17 00:00:00 2001 From: Chris Brown Date: Fri, 24 Apr 2026 14:32:09 +0100 Subject: [PATCH] Support OpenShift arbitrary UIDs (restricted-v2 SCC) Make container images compatible with OpenShift 4.20's default security context which assigns arbitrary UIDs with GID 0 (root group): - Add vespa user to root group (-G root) in both Dockerfiles - Make /etc/passwd group-writable for runtime UID injection - Set root group ownership with g+w on all writable directories - Entrypoint: inject passwd entry for arbitrary UIDs so id/whoami work Co-Authored-By: Claude Opus 4.7 --- Dockerfile | 7 ++++++- Dockerfile.minimal | 9 ++++++++- include/start-container.sh | 9 +++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index ce968b1..7f55740 100644 --- a/Dockerfile +++ b/Dockerfile @@ -40,7 +40,7 @@ ARG SOURCE_GITREF=v$VESPA_VERSION ADD include/start-container.sh /usr/local/bin/start-container.sh RUN groupadd -g 1000 vespa && \ - useradd -u 1000 -g vespa -d /opt/vespa -s /sbin/nologin vespa + useradd -u 1000 -g vespa -G root -d /opt/vespa -s /sbin/nologin vespa RUN --mount=type=bind,target=/files,source=.,ro \ if [[ -d /files/rpms ]]; then echo -e "[vespa-rpms-local]\nname=Local Vespa RPMs\nbaseurl=file:///files/rpms/\nenabled=1\ngpgcheck=0" > /etc/yum.repos.d/vespa-rpms-local.repo; fi && \ @@ -49,6 +49,11 @@ RUN --mount=type=bind,target=/files,source=.,ro \ rm -f /etc/yum.repos.d/vespa-rpms-local.repo && \ rm -rf /var/cache/dnf +RUN chmod g+w /etc/passwd && \ + chgrp -R 0 /opt/vespa/logs /opt/vespa/var /opt/vespa/secure /opt/vespa/var/zookeeper && \ + chmod -R g+w /opt/vespa/logs /opt/vespa/var /opt/vespa/secure /opt/vespa/var/zookeeper && \ + chgrp 0 /opt/vespa/tmp 2>/dev/null; chmod g+w /opt/vespa/tmp 2>/dev/null; true + LABEL org.opencontainers.image.authors="Vespa (https://vespa.ai)" \ org.opencontainers.image.description="Easily serve your big data - generate responses in milliseconds at any scale and with any traffic volume. Read more at the Vespa project https://vespa.ai" \ org.opencontainers.image.documentation="https://docs.vespa.ai" \ diff --git a/Dockerfile.minimal b/Dockerfile.minimal index 35f5f17..274db98 100644 --- a/Dockerfile.minimal +++ b/Dockerfile.minimal @@ -6,7 +6,7 @@ ARG ROOTFS_INSTALL_DIR=/tmp_install # Add vespa user before installing the Vespa RPMs to get a fixed UID/GID RUN groupadd -g 1000 vespa && \ - useradd -u 1000 -g vespa -d /opt/vespa -s /sbin/nologin vespa && \ + useradd -u 1000 -g vespa -G root -d /opt/vespa -s /sbin/nologin vespa && \ mkdir -p $ROOTFS_INSTALL_DIR/etc && \ cp -a /etc/passwd /etc/group /etc/shadow $ROOTFS_INSTALL_DIR/etc @@ -78,6 +78,13 @@ RUN mkdir -p $ROOTFS_INSTALL_DIR/run/lock && \ chroot $ROOTFS_INSTALL_DIR truncate --size 0 /etc/machine-id && \ echo 'LANG=C.utf8' > $ROOTFS_INSTALL_DIR/etc/locale.conf +# OpenShift compatibility: make writable dirs accessible by GID 0 (arbitrary UIDs) +RUN chmod g+w $ROOTFS_INSTALL_DIR/etc/passwd && \ + chgrp -R 0 $ROOTFS_INSTALL_DIR/opt/vespa/logs $ROOTFS_INSTALL_DIR/opt/vespa/var \ + $ROOTFS_INSTALL_DIR/opt/vespa/secure $ROOTFS_INSTALL_DIR/opt/vespa/var/zookeeper && \ + chmod -R g+w $ROOTFS_INSTALL_DIR/opt/vespa/logs $ROOTFS_INSTALL_DIR/opt/vespa/var \ + $ROOTFS_INSTALL_DIR/opt/vespa/secure $ROOTFS_INSTALL_DIR/opt/vespa/var/zookeeper + # Build the image FROM scratch ARG VESPA_VERSION diff --git a/include/start-container.sh b/include/start-container.sh index 4f0159e..21aabaf 100755 --- a/include/start-container.sh +++ b/include/start-container.sh @@ -3,6 +3,15 @@ set -e +# OpenShift runs containers with arbitrary UIDs not present in /etc/passwd. +# Inject a passwd entry so that utilities like 'id' and 'whoami' work. +if ! whoami &>/dev/null 2>&1; then + if [ -w /etc/passwd ]; then + echo "vespa:x:$(id -u):0:Vespa:/opt/vespa:/bin/bash" >> /etc/passwd + fi + export VESPA_USER=vespa +fi + if [ $# -gt 1 ]; then echo "Allowed arguments to entrypoint are {configserver,services}." exit 1