Skip to content

Commit fa9866b

Browse files
authored
fix: Set correct user IDs for container images build by nix (#619)
I noticed this while working on stackabletech/operator-rs#1205, as the bundle-builder was rejected by Kubernetes up as it wanted to run as root.
1 parent cb96797 commit fa9866b

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

template/default.nix

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ rec {
133133
${entrypoint} crd > $out
134134
'';
135135

136+
# The unprivileged user that the operator runs as.
137+
# These values must be kept in sync with docker/Dockerfile!
138+
stackableUserName = "stackable";
139+
stackableUserUid = 782252253;
140+
stackableUserGid = 574654813;
141+
136142
# We're building the docker image *for* Linux, but we need to
137143
# build it in the local environment so that the generated load-image
138144
# can run locally.
@@ -150,9 +156,37 @@ rec {
150156
pkgsTarget.coreutils
151157
pkgsTarget.util-linuxMinimal
152158
];
159+
160+
# Nix images don't contain a user database, so create a minimal one containing the same user
161+
# that docker/Dockerfile creates via groupadd/useradd. Without it the UID cannot be resolved to
162+
# a name and a home directory, which breaks tools such as `whoami` and makes for a confusing
163+
# shell prompt when using `kubectl exec`.
164+
extraCommands = ''
165+
mkdir -p etc stackable
166+
cat > etc/passwd <<EOF
167+
root:x:0:0:root:/root:/bin/bash
168+
${stackableUserName}:x:${toString stackableUserUid}:${toString stackableUserGid}:${stackableUserName}:/stackable:/bin/bash
169+
EOF
170+
cat > etc/group <<EOF
171+
root:x:0:
172+
${stackableUserName}:x:${toString stackableUserGid}:
173+
EOF
174+
'';
175+
# All files and folders are owned by the root group to support running as arbitrary users.
176+
# This is best practice as all container users will belong to the root group (0).
177+
# Same as in docker/Dockerfile.
178+
fakeRootCommands = ''
179+
chown -R ${toString stackableUserUid}:0 stackable
180+
chmod -R g=u stackable
181+
'';
182+
153183
config = {
154184
Entrypoint = [ entrypoint ];
155185
Cmd = [ "run" ];
186+
# Mirrors the `USER` instruction in docker/Dockerfile. Besides not running as root, this is
187+
# also required for Pods that set `runAsNonRoot: true` without an explicit `runAsUser`,
188+
# because the kubelet refuses to start containers whose image would run as root.
189+
User = toString stackableUserUid;
156190
};
157191
};
158192
docker = pkgsLocal.linkFarm "${dockerImage.name}-docker" [

template/docker/Dockerfile.j2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ ARG VERSION
2626
ARG RELEASE="1"
2727

2828
# These are chosen at random and are this high on purpose to have very little chance to clash with an existing user or group on the host system
29+
# NOTE: Please also update default.nix accordingly!
2930
ARG STACKABLE_USER_GID="574654813"
3031
ARG STACKABLE_USER_UID="782252253"
3132
ARG STACKABLE_USER_NAME="stackable"

0 commit comments

Comments
 (0)