From d5dc748d252dd3c8646ba78fe855cc79f34186dc Mon Sep 17 00:00:00 2001 From: Timur Abdullin Date: Mon, 12 Oct 2026 21:12:40 +0300 Subject: [PATCH 1/3] build(docker): switch runtime images to distroless and run as non-root Replace the outdated debian:12.0-slim runner base with gcr.io/distroless/static-debian13. All Go services are built with CGO_ENABLED=0, so a static base is sufficient. Distroless also ships the CA bundle that x509.SystemCertPool() relies on (debian slim does not), plus tzdata and a nonroot user. All services except runtime-monitor now run as UID 65532. The numeric UID lets the kubelet verify runAsNonRoot. WORKDIR is set to / because TLS and DB certificates are loaded by relative paths. runtime-monitor stays root because it talks to Tetragon, which runs as root in the same pod. Co-Authored-By: Claude Opus 5.5 --- auth-center/Dockerfile | 7 ++++++- cluster-manager/Dockerfile | 7 ++++++- cs-manager/Dockerfile | 7 ++++++- event-processor/Dockerfile | 7 ++++++- history-api/Dockerfile | 7 ++++++- kube-manager/Dockerfile | 7 ++++++- notifier/Dockerfile | 7 ++++++- policy-enforcer/Dockerfile | 7 ++++++- public-api/Dockerfile | 7 ++++++- runtime-monitor/Dockerfile | 3 ++- 10 files changed, 56 insertions(+), 10 deletions(-) diff --git a/auth-center/Dockerfile b/auth-center/Dockerfile index 7640a038..b0233055 100644 --- a/auth-center/Dockerfile +++ b/auth-center/Dockerfile @@ -25,7 +25,7 @@ COPY lib/ lib/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d auth-center build -FROM debian:12.0-slim AS runner +FROM gcr.io/distroless/static-debian13:nonroot AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="Auth center service exposes Users, Role and Auth control interfaces" @@ -38,5 +38,10 @@ COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / COPY --from=builder /go/src/repo/${APP_NAME}/*.txt / COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops +# Certificates are loaded by relative paths, so run from the directory they are copied to. +WORKDIR / +# Numeric UID lets Kubernetes verify runAsNonRoot. +USER 65532:65532 + EXPOSE 8000 9000 ENTRYPOINT ["/app"] diff --git a/cluster-manager/Dockerfile b/cluster-manager/Dockerfile index 779f9502..7369200b 100644 --- a/cluster-manager/Dockerfile +++ b/cluster-manager/Dockerfile @@ -25,7 +25,7 @@ COPY lib/ lib/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d cluster-manager build -FROM debian:12.0-slim AS runner +FROM gcr.io/distroless/static-debian13:nonroot AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="This is a Cluster Manager service which controls child clusters from the main cluster" @@ -37,5 +37,10 @@ COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops +# Certificates are loaded by relative paths, so run from the directory they are copied to. +WORKDIR / +# Numeric UID lets Kubernetes verify runAsNonRoot. +USER 65532:65532 + EXPOSE 8000 9000 ENTRYPOINT ["/app"] diff --git a/cs-manager/Dockerfile b/cs-manager/Dockerfile index cbac7023..91619204 100644 --- a/cs-manager/Dockerfile +++ b/cs-manager/Dockerfile @@ -26,7 +26,7 @@ COPY cluster-manager/api/ cluster-manager/api/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d cs-manager build -FROM debian:12.0-slim AS runner +FROM gcr.io/distroless/static-debian13:nonroot AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="CS Manager is responsible for installation-wide tasks such as child cluster registration, serving /api/v1/info/* endpoints, etc" @@ -39,5 +39,10 @@ COPY --from=builder /go/src/repo/${APP_NAME}/cmd/unregister/unregister /unregist COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops +# Certificates are loaded by relative paths, so run from the directory they are copied to. +WORKDIR / +# Numeric UID lets Kubernetes verify runAsNonRoot. +USER 65532:65532 + EXPOSE 8000 9000 ENTRYPOINT ["/app"] diff --git a/event-processor/Dockerfile b/event-processor/Dockerfile index 898ec925..f01f95ab 100644 --- a/event-processor/Dockerfile +++ b/event-processor/Dockerfile @@ -31,7 +31,7 @@ COPY kube-manager/api/ kube-manager/api/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d event-processor build -FROM debian:12.0-slim AS runner +FROM gcr.io/distroless/static-debian13:nonroot AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="Event processor processes events from `runtime-monitor`" @@ -44,5 +44,10 @@ COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / COPY --from=builder /go/src/repo/event-processor/deploy/*.wasm /deploy/ COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops +# Certificates are loaded by relative paths, so run from the directory they are copied to. +WORKDIR / +# Numeric UID lets Kubernetes verify runAsNonRoot. +USER 65532:65532 + EXPOSE 8000 9000 ENTRYPOINT ["/app"] diff --git a/history-api/Dockerfile b/history-api/Dockerfile index 7d050001..cf0f672b 100644 --- a/history-api/Dockerfile +++ b/history-api/Dockerfile @@ -28,7 +28,7 @@ COPY policy-enforcer/pkg/model/ policy-enforcer/pkg/model/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d history-api build -FROM debian:12.0-slim AS runner +FROM gcr.io/distroless/static-debian13:nonroot AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="History API service saves and retrieves historic data in the system" @@ -40,5 +40,10 @@ COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops +# Certificates are loaded by relative paths, so run from the directory they are copied to. +WORKDIR / +# Numeric UID lets Kubernetes verify runAsNonRoot. +USER 65532:65532 + EXPOSE 8000 9000 ENTRYPOINT ["/app"] diff --git a/kube-manager/Dockerfile b/kube-manager/Dockerfile index 497b4b14..99974dce 100644 --- a/kube-manager/Dockerfile +++ b/kube-manager/Dockerfile @@ -25,7 +25,7 @@ COPY lib/ lib/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d kube-manager build -FROM debian:12.0-slim AS runner +FROM gcr.io/distroless/static-debian13:nonroot AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="The Kube Manager service collects information about entities in the K8S cluster and provides interfaces for obtaining this data" @@ -37,5 +37,10 @@ COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops +# Certificates are loaded by relative paths, so run from the directory they are copied to. +WORKDIR / +# Numeric UID lets Kubernetes verify runAsNonRoot. +USER 65532:65532 + EXPOSE 8000 9000 ENTRYPOINT ["/app"] diff --git a/notifier/Dockerfile b/notifier/Dockerfile index 8720b0b0..bb34c17d 100644 --- a/notifier/Dockerfile +++ b/notifier/Dockerfile @@ -30,7 +30,7 @@ COPY event-processor/api/ event-processor/api/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d notifier build -FROM debian:12.0-slim AS runner +FROM gcr.io/distroless/static-debian13:nonroot AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="Notifier service is responsible for sending notifications" @@ -43,5 +43,10 @@ COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / COPY --from=builder /go/src/repo/notifier/templates /templates COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops +# Certificates are loaded by relative paths, so run from the directory they are copied to. +WORKDIR / +# Numeric UID lets Kubernetes verify runAsNonRoot. +USER 65532:65532 + EXPOSE 8000 9000 ENTRYPOINT ["/app"] diff --git a/policy-enforcer/Dockerfile b/policy-enforcer/Dockerfile index 6ff3a237..4b69a217 100644 --- a/policy-enforcer/Dockerfile +++ b/policy-enforcer/Dockerfile @@ -25,7 +25,7 @@ COPY lib/ lib/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d policy-enforcer build -FROM debian:12.0-slim AS runner +FROM gcr.io/distroless/static-debian13:nonroot AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="Policy Enforcer service evaluates Policy and exposes Scope and Rule control interfaces" @@ -37,5 +37,10 @@ COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops +# Certificates are loaded by relative paths, so run from the directory they are copied to. +WORKDIR / +# Numeric UID lets Kubernetes verify runAsNonRoot. +USER 65532:65532 + EXPOSE 8000 9000 ENTRYPOINT ["/app"] diff --git a/public-api/Dockerfile b/public-api/Dockerfile index 5bea363a..726c1ccc 100644 --- a/public-api/Dockerfile +++ b/public-api/Dockerfile @@ -29,7 +29,7 @@ COPY kube-manager/ kube-manager/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d public-api build -FROM debian:12.0-slim AS runner +FROM gcr.io/distroless/static-debian13:nonroot AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="REST API for using CS functionality in client services" @@ -41,5 +41,10 @@ COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops +# Certificates are loaded by relative paths, so run from the directory they are copied to. +WORKDIR / +# Numeric UID lets Kubernetes verify runAsNonRoot. +USER 65532:65532 + EXPOSE 8000 9000 ENTRYPOINT ["/app"] diff --git a/runtime-monitor/Dockerfile b/runtime-monitor/Dockerfile index fbcf4691..c47d2968 100644 --- a/runtime-monitor/Dockerfile +++ b/runtime-monitor/Dockerfile @@ -27,7 +27,8 @@ COPY lib/ lib/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d runtime-monitor build -FROM debian:12.0-slim AS runner +# Runs as root: runtime-monitor talks to Tetragon, which runs as root in the same pod. +FROM gcr.io/distroless/static-debian13 AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="Runtime monitor monitors runtime events in k8s" From f07e85b97894553bfdc1a6ada987da76db6ba67a Mon Sep 17 00:00:00 2001 From: Timur Abdullin Date: Mon, 12 Oct 2026 21:12:51 +0300 Subject: [PATCH 2/3] build(docker): drop gops CLI from runtime images The gops binary was copied into every image only for interactive debugging and added its own set of vulnerable dependencies. The gops agent embedded in the services is unaffected; the CLI can still be used from a workstation or an ephemeral debug container (kubectl debug). Co-Authored-By: Claude Opus 5.5 --- auth-center/Dockerfile | 5 ----- cluster-manager/Dockerfile | 5 ----- cs-manager/Dockerfile | 5 ----- event-processor/Dockerfile | 5 ----- history-api/Dockerfile | 5 ----- kube-manager/Dockerfile | 5 ----- notifier/Dockerfile | 5 ----- policy-enforcer/Dockerfile | 5 ----- public-api/Dockerfile | 5 ----- runtime-monitor/Dockerfile | 5 ----- 10 files changed, 50 deletions(-) diff --git a/auth-center/Dockerfile b/auth-center/Dockerfile index b0233055..7631163e 100644 --- a/auth-center/Dockerfile +++ b/auth-center/Dockerfile @@ -15,10 +15,6 @@ COPY go.mod go.sum ./ COPY vendor/ vendor/ ENV GOCACHE=/root/.cache/go-build -RUN --mount=type=cache,target="/root/.cache/go-build" \ - mkdir -p bin && \ - GOBIN=/go/src/repo/bin go install github.com/google/gops - COPY --from=tools /usr/bin/task /usr/bin COPY auth-center/ auth-center/ COPY lib/ lib/ @@ -36,7 +32,6 @@ ARG APP_NAME=auth-center COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / COPY --from=builder /go/src/repo/${APP_NAME}/*.txt / -COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops # Certificates are loaded by relative paths, so run from the directory they are copied to. WORKDIR / diff --git a/cluster-manager/Dockerfile b/cluster-manager/Dockerfile index 7369200b..1e01adc2 100644 --- a/cluster-manager/Dockerfile +++ b/cluster-manager/Dockerfile @@ -15,10 +15,6 @@ COPY go.mod go.sum ./ COPY vendor/ vendor/ ENV GOCACHE=/root/.cache/go-build -RUN --mount=type=cache,target="/root/.cache/go-build" \ - mkdir -p bin && \ - GOBIN=/go/src/repo/bin go install github.com/google/gops - COPY --from=tools /usr/bin/task /usr/bin COPY cluster-manager/ cluster-manager/ COPY lib/ lib/ @@ -35,7 +31,6 @@ ARG APP_NAME=cluster-manager COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / -COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops # Certificates are loaded by relative paths, so run from the directory they are copied to. WORKDIR / diff --git a/cs-manager/Dockerfile b/cs-manager/Dockerfile index 91619204..a7153b95 100644 --- a/cs-manager/Dockerfile +++ b/cs-manager/Dockerfile @@ -15,10 +15,6 @@ COPY go.mod go.sum ./ COPY vendor/ vendor/ ENV GOCACHE=/root/.cache/go-build -RUN --mount=type=cache,target="/root/.cache/go-build" \ - mkdir -p bin && \ - GOBIN=/go/src/repo/bin go install github.com/google/gops - COPY --from=tools /usr/bin/task /usr/bin COPY cs-manager/ cs-manager/ COPY lib/ lib/ @@ -37,7 +33,6 @@ ARG APP_NAME=cs-manager COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/unregister/unregister /unregister COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / -COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops # Certificates are loaded by relative paths, so run from the directory they are copied to. WORKDIR / diff --git a/event-processor/Dockerfile b/event-processor/Dockerfile index f01f95ab..18044cc5 100644 --- a/event-processor/Dockerfile +++ b/event-processor/Dockerfile @@ -15,10 +15,6 @@ COPY go.mod go.sum ./ COPY vendor/ vendor/ ENV GOCACHE=/root/.cache/go-build -RUN --mount=type=cache,target="/root/.cache/go-build" \ - mkdir -p bin && \ - GOBIN=/go/src/repo/bin go install github.com/google/gops - COPY --from=tools /usr/bin/task /usr/bin COPY event-processor/ event-processor/ COPY lib/ lib/ @@ -42,7 +38,6 @@ ARG APP_NAME=event-processor COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / COPY --from=builder /go/src/repo/event-processor/deploy/*.wasm /deploy/ -COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops # Certificates are loaded by relative paths, so run from the directory they are copied to. WORKDIR / diff --git a/history-api/Dockerfile b/history-api/Dockerfile index cf0f672b..9ef02642 100644 --- a/history-api/Dockerfile +++ b/history-api/Dockerfile @@ -15,10 +15,6 @@ COPY go.mod go.sum ./ COPY vendor/ vendor/ ENV GOCACHE=/root/.cache/go-build -RUN --mount=type=cache,target="/root/.cache/go-build" \ - mkdir -p bin && \ - GOBIN=/go/src/repo/bin go install github.com/google/gops - COPY --from=tools /usr/bin/task /usr/bin COPY history-api/ history-api/ COPY lib/ lib/ @@ -38,7 +34,6 @@ ARG APP_NAME=history-api COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / -COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops # Certificates are loaded by relative paths, so run from the directory they are copied to. WORKDIR / diff --git a/kube-manager/Dockerfile b/kube-manager/Dockerfile index 99974dce..27edff49 100644 --- a/kube-manager/Dockerfile +++ b/kube-manager/Dockerfile @@ -15,10 +15,6 @@ COPY go.mod go.sum ./ COPY vendor/ vendor/ ENV GOCACHE=/root/.cache/go-build -RUN --mount=type=cache,target="/root/.cache/go-build" \ - mkdir -p bin && \ - GOBIN=/go/src/repo/bin go install github.com/google/gops - COPY --from=tools /usr/bin/task /usr/bin COPY kube-manager/ kube-manager/ COPY lib/ lib/ @@ -35,7 +31,6 @@ ARG APP_NAME=kube-manager COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / -COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops # Certificates are loaded by relative paths, so run from the directory they are copied to. WORKDIR / diff --git a/notifier/Dockerfile b/notifier/Dockerfile index bb34c17d..5ff73227 100644 --- a/notifier/Dockerfile +++ b/notifier/Dockerfile @@ -15,10 +15,6 @@ COPY go.mod go.sum ./ COPY vendor/ vendor/ ENV GOCACHE=/root/.cache/go-build -RUN --mount=type=cache,target="/root/.cache/go-build" \ - mkdir -p bin && \ - GOBIN=/go/src/repo/bin go install github.com/google/gops - COPY --from=tools /usr/bin/task /usr/bin COPY notifier/ notifier/ COPY lib/ lib/ @@ -41,7 +37,6 @@ ARG APP_NAME=notifier COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / COPY --from=builder /go/src/repo/notifier/templates /templates -COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops # Certificates are loaded by relative paths, so run from the directory they are copied to. WORKDIR / diff --git a/policy-enforcer/Dockerfile b/policy-enforcer/Dockerfile index 4b69a217..a381c99b 100644 --- a/policy-enforcer/Dockerfile +++ b/policy-enforcer/Dockerfile @@ -15,10 +15,6 @@ COPY go.mod go.sum ./ COPY vendor/ vendor/ ENV GOCACHE=/root/.cache/go-build -RUN --mount=type=cache,target="/root/.cache/go-build" \ - mkdir -p bin && \ - GOBIN=/go/src/repo/bin go install github.com/google/gops - COPY --from=tools /usr/bin/task /usr/bin COPY policy-enforcer/ policy-enforcer/ COPY lib/ lib/ @@ -35,7 +31,6 @@ ARG APP_NAME=policy-enforcer COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / -COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops # Certificates are loaded by relative paths, so run from the directory they are copied to. WORKDIR / diff --git a/public-api/Dockerfile b/public-api/Dockerfile index 726c1ccc..15e6617d 100644 --- a/public-api/Dockerfile +++ b/public-api/Dockerfile @@ -15,10 +15,6 @@ COPY go.mod go.sum ./ COPY vendor/ vendor/ ENV GOCACHE=/root/.cache/go-build -RUN --mount=type=cache,target="/root/.cache/go-build" \ - mkdir -p bin && \ - GOBIN=/go/src/repo/bin go install github.com/google/gops - COPY --from=tools /usr/bin/task /usr/bin COPY public-api/ public-api/ COPY lib/ lib/ @@ -39,7 +35,6 @@ ARG APP_NAME=public-api COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / -COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops # Certificates are loaded by relative paths, so run from the directory they are copied to. WORKDIR / diff --git a/runtime-monitor/Dockerfile b/runtime-monitor/Dockerfile index c47d2968..1d900165 100644 --- a/runtime-monitor/Dockerfile +++ b/runtime-monitor/Dockerfile @@ -17,10 +17,6 @@ COPY pkg/tools/tools.go pkg/tools/ ENV GOCACHE=/root/.cache/go-build -RUN --mount=type=cache,target="/root/.cache/go-build" \ - mkdir -p bin && \ - GOBIN=/go/src/repo/bin go install github.com/google/gops - COPY --from=tools /usr/bin/task /usr/bin COPY runtime-monitor/ runtime-monitor/ COPY lib/ lib/ @@ -38,7 +34,6 @@ ARG APP_NAME=runtime-monitor COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/${APP_NAME} /app COPY --from=builder /go/src/repo/${APP_NAME}/cmd/${APP_NAME}/*.pem / -COPY --from=builder /go/src/repo/bin/gops /usr/bin/gops EXPOSE 8000 9000 ENTRYPOINT ["/app"] From f96c08d143e8f596a2d92c42c409fb09014cc2a4 Mon Sep 17 00:00:00 2001 From: Timur Abdullin Date: Wed, 14 Oct 2026 13:18:38 +0300 Subject: [PATCH 3/3] build(docker): use runtime-radar-base as the non-root runner image Switch the nine non-root services from gcr.io/distroless/static-debian13 to the project's apko-built Wolfi base image (#65), as suggested in review. The base ships ca-certificates-bundle and tzdata and runs as UID 65532, so the existing USER and WORKDIR directives stay valid. runtime-monitor is unchanged: it must run as root, while the new base defaults to the nonroot user. Co-Authored-By: Claude Opus 5.5 --- auth-center/Dockerfile | 2 +- cluster-manager/Dockerfile | 2 +- cs-manager/Dockerfile | 2 +- event-processor/Dockerfile | 2 +- history-api/Dockerfile | 2 +- kube-manager/Dockerfile | 2 +- notifier/Dockerfile | 2 +- policy-enforcer/Dockerfile | 2 +- public-api/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/auth-center/Dockerfile b/auth-center/Dockerfile index 7631163e..85c6d32f 100644 --- a/auth-center/Dockerfile +++ b/auth-center/Dockerfile @@ -21,7 +21,7 @@ COPY lib/ lib/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d auth-center build -FROM gcr.io/distroless/static-debian13:nonroot AS runner +FROM ghcr.io/runtime-radar/runtime-radar-base:20261014 AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="Auth center service exposes Users, Role and Auth control interfaces" diff --git a/cluster-manager/Dockerfile b/cluster-manager/Dockerfile index 1e01adc2..82aed045 100644 --- a/cluster-manager/Dockerfile +++ b/cluster-manager/Dockerfile @@ -21,7 +21,7 @@ COPY lib/ lib/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d cluster-manager build -FROM gcr.io/distroless/static-debian13:nonroot AS runner +FROM ghcr.io/runtime-radar/runtime-radar-base:20261014 AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="This is a Cluster Manager service which controls child clusters from the main cluster" diff --git a/cs-manager/Dockerfile b/cs-manager/Dockerfile index a7153b95..1c0fc76f 100644 --- a/cs-manager/Dockerfile +++ b/cs-manager/Dockerfile @@ -22,7 +22,7 @@ COPY cluster-manager/api/ cluster-manager/api/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d cs-manager build -FROM gcr.io/distroless/static-debian13:nonroot AS runner +FROM ghcr.io/runtime-radar/runtime-radar-base:20261014 AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="CS Manager is responsible for installation-wide tasks such as child cluster registration, serving /api/v1/info/* endpoints, etc" diff --git a/event-processor/Dockerfile b/event-processor/Dockerfile index 18044cc5..baf4e293 100644 --- a/event-processor/Dockerfile +++ b/event-processor/Dockerfile @@ -27,7 +27,7 @@ COPY kube-manager/api/ kube-manager/api/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d event-processor build -FROM gcr.io/distroless/static-debian13:nonroot AS runner +FROM ghcr.io/runtime-radar/runtime-radar-base:20261014 AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="Event processor processes events from `runtime-monitor`" diff --git a/history-api/Dockerfile b/history-api/Dockerfile index 9ef02642..0f827c23 100644 --- a/history-api/Dockerfile +++ b/history-api/Dockerfile @@ -24,7 +24,7 @@ COPY policy-enforcer/pkg/model/ policy-enforcer/pkg/model/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d history-api build -FROM gcr.io/distroless/static-debian13:nonroot AS runner +FROM ghcr.io/runtime-radar/runtime-radar-base:20261014 AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="History API service saves and retrieves historic data in the system" diff --git a/kube-manager/Dockerfile b/kube-manager/Dockerfile index 27edff49..487ade04 100644 --- a/kube-manager/Dockerfile +++ b/kube-manager/Dockerfile @@ -21,7 +21,7 @@ COPY lib/ lib/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d kube-manager build -FROM gcr.io/distroless/static-debian13:nonroot AS runner +FROM ghcr.io/runtime-radar/runtime-radar-base:20261014 AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="The Kube Manager service collects information about entities in the K8S cluster and provides interfaces for obtaining this data" diff --git a/notifier/Dockerfile b/notifier/Dockerfile index 5ff73227..b83a13e2 100644 --- a/notifier/Dockerfile +++ b/notifier/Dockerfile @@ -26,7 +26,7 @@ COPY event-processor/api/ event-processor/api/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d notifier build -FROM gcr.io/distroless/static-debian13:nonroot AS runner +FROM ghcr.io/runtime-radar/runtime-radar-base:20261014 AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="Notifier service is responsible for sending notifications" diff --git a/policy-enforcer/Dockerfile b/policy-enforcer/Dockerfile index a381c99b..fcfb3146 100644 --- a/policy-enforcer/Dockerfile +++ b/policy-enforcer/Dockerfile @@ -21,7 +21,7 @@ COPY lib/ lib/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d policy-enforcer build -FROM gcr.io/distroless/static-debian13:nonroot AS runner +FROM ghcr.io/runtime-radar/runtime-radar-base:20261014 AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="Policy Enforcer service evaluates Policy and exposes Scope and Rule control interfaces" diff --git a/public-api/Dockerfile b/public-api/Dockerfile index 15e6617d..e861e949 100644 --- a/public-api/Dockerfile +++ b/public-api/Dockerfile @@ -25,7 +25,7 @@ COPY kube-manager/ kube-manager/ RUN --mount=type=cache,target="/root/.cache/go-build" task -d public-api build -FROM gcr.io/distroless/static-debian13:nonroot AS runner +FROM ghcr.io/runtime-radar/runtime-radar-base:20261014 AS runner LABEL org.opencontainers.image.source=https://github.com/runtime-radar/runtime-radar LABEL org.opencontainers.image.description="REST API for using CS functionality in client services"