From 304fb0f0cb6aa22c5c5214be76d264f24135cff9 Mon Sep 17 00:00:00 2001 From: Daniel Genis Date: Tue, 21 Apr 2026 14:24:29 +0200 Subject: [PATCH] fix(k8s): use UID 1001 to align with upstream Ubuntu 24.04 ships with a built-in 'ubuntu' user at UID 1000. Upstream moved to UID 1001 to avoid needing to delete this user. Aligning our branch with this change simplifies future merges. Changes: - Dockerfile: agent user now UID/GID 1001 (no userdel needed) - k8s-workload-service: pod securityContext uses 1001 - initContainer chown uses 1001:1001 --- apps/api/src/services/k8s-workload-service.ts | 14 +++++++------- images/base.Dockerfile | 8 +++----- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/apps/api/src/services/k8s-workload-service.ts b/apps/api/src/services/k8s-workload-service.ts index 49225610..6cb49c1e 100644 --- a/apps/api/src/services/k8s-workload-service.ts +++ b/apps/api/src/services/k8s-workload-service.ts @@ -528,14 +528,14 @@ export class K8sWorkloadManager { } // Pod-level security context for StatefulSets — ensures PVC mounts are - // writable by the agent user (UID/GID 1000). fsGroup sets the group owner - // of all files in mounted volumes. UID 1000 matches the `agent` user + // writable by the agent user (UID/GID 1001). fsGroup sets the group owner + // of all files in mounted volumes. UID 1001 matches the `agent` user // created in images/base.Dockerfile and owns /workspace in the image. if (restartPolicy === "Always") { const podSecCtx = new V1PodSecurityContext(); - podSecCtx.fsGroup = 1000; - podSecCtx.runAsUser = 1000; - podSecCtx.runAsGroup = 1000; + podSecCtx.fsGroup = 1001; + podSecCtx.runAsUser = 1001; + podSecCtx.runAsGroup = 1001; podSpec.securityContext = podSecCtx; } @@ -550,7 +550,7 @@ export class K8sWorkloadManager { const initContainers: V1Container[] = []; // For StatefulSets, prepend an initContainer that chowns the home PVC - // mount to UID 1000 (the `agent` user in images/base.Dockerfile). This + // mount to UID 1001 (the `agent` user in images/base.Dockerfile). This // is necessary because some storage classes (docker-desktop's hostpath, // GKE default) don't honor the pod's fsGroup setting, leaving the mount // root-owned and unwritable by the main container. Running chown as @@ -561,7 +561,7 @@ export class K8sWorkloadManager { permInit.name = "home-perm-fix"; permInit.image = spec.image; permInit.imagePullPolicy = spec.imagePullPolicy ?? "IfNotPresent"; - permInit.command = ["sh", "-c", "chown -R 1000:1000 /home/agent && chmod 755 /home/agent"]; + permInit.command = ["sh", "-c", "chown -R 1001:1001 /home/agent && chmod 755 /home/agent"]; const initSec = new V1SecurityContext(); initSec.runAsUser = 0; initSec.runAsGroup = 0; diff --git a/images/base.Dockerfile b/images/base.Dockerfile index f2f5c767..098fb5de 100644 --- a/images/base.Dockerfile +++ b/images/base.Dockerfile @@ -69,11 +69,9 @@ COPY scripts/optio-gh-wrapper /usr/local/bin/optio-gh-wrapper COPY scripts/optio-glab-wrapper /usr/local/bin/optio-glab-wrapper RUN chmod +x /usr/local/bin/optio-git-credential /usr/local/bin/optio-gh-wrapper /usr/local/bin/optio-glab-wrapper -# Non-root user (UID 1000 to match k8s securityContext) -# Ubuntu 24.04 ships with 'ubuntu' user at UID 1000 — remove it first -RUN userdel -r ubuntu 2>/dev/null || true \ - && groupadd -g 1000 agent \ - && useradd -m -s /bin/bash -u 1000 -g 1000 agent \ +# Non-root user (UID 1001 to match k8s securityContext) +RUN groupadd -g 1001 agent \ + && useradd -m -s /bin/bash -u 1001 -g 1001 agent \ && chown -R agent:agent /workspace USER agent WORKDIR /workspace