We have had two relevant practices for the container images we publish:
- Don't change the user.
- Don't add users.
You can see that with our .NET 7 container images.
$ docker run --rm debian:bullseye-slim whoami
root
$ docker run --rm mcr.microsoft.com/dotnet/aspnet:7.0-bullseye-slim whoami
root
$ docker run --rm debian:bullseye-slim cat /etc/passwd | wc -l
19
$ docker run --rm mcr.microsoft.com/dotnet/aspnet:7.0-bullseye-slim cat /etc/passwd | wc -l
19
The images are identical with respect to users. The 7.0
tag is identical to 7.0-bullseye-slim
(for Linux images).
Note: users are stored in the /etc/passwd
file on Linux, one per line. wc -l
provides a line count, giving us the number of users.
Starting with .NET 8, we've added a non-root user, app
. That removes the second of the two practices, going forward. We've also switched to using Debian Bookworm.
$ docker run --rm debian:bookworm-slim whoami
root
$ docker run --rm mcr.microsoft.com/dotnet/aspnet:8.0-preview-bookworm-slim whoami
root
$ docker run --rm debian:bookworm-slim cat /etc/passwd | wc -l
18
$ docker run --rm mcr.microsoft.com/dotnet/aspnet:8.0-preview-bookworm-slim cat /etc/passwd | wc -l
19
$ docker run --rm mcr.microsoft.com/dotnet/aspnet:8.0-preview-bookworm-slim cat /etc/passwd | tail -n 1
app:x:64198:64198::/home/app:/bin/sh
Our user gets added as the last line in the file, which explains the use of tail -n 1
.
We see some differences now. First, both images continue to use the root
user. The .NET image adds an app
user. Debian removed a user (gnats
) that was in Bullseye, which explains the differing user count across the two Debian versions, although that's irrelevant to our topic.
We can try whoami
with the app user.
$ docker run --rm -u app mcr.microsoft.com/dotnet/aspnet:8.0-preview-bookworm-slim whoami
app
That works.
This user is available in all .NET Linux images. It is added as part our runtime-deps
layer.
$ docker run --rm -u app mcr.microsoft.com/dotnet/runtime-deps:8.0-preview-bookworm-slim whoami
app
It is also available in our Alpine and Ubuntu images:
$ docker run --rm -u app mcr.microsoft.com/dotnet/runtime-deps:8.0-preview-alpine whoami
app
$ docker run --rm -u app mcr.microsoft.com/dotnet/runtime-deps:8.0-preview-jammy whoami
app