Skip to content

Instantly share code, notes, and snippets.

@richlander
Last active February 23, 2023 02:57
Show Gist options
  • Save richlander/3ad3406f2cd1563f8ef40c0c4ab8caf7 to your computer and use it in GitHub Desktop.
Save richlander/3ad3406f2cd1563f8ef40c0c4ab8caf7 to your computer and use it in GitHub Desktop.
.NET Container Demo

Playing with .NET 8 Containers

We just shipped a cool new scenario for .NET, which is making it really easy to run .NET 8 container images as a non-root user.

Friends don't let friends run as root

We should all get T-Shirts that say that.

Let's take a quick look using our favourite aspnetapp sample. I'm going to use WSL. I'll show you everthing I do. I use the patterns that are easiest for me, which might not be the same for you.

Download .NET 8 Preview 1

rich@mazama:~$ curl -Lo dotnet.tar.gz https://download.visualstudio.microsoft.com/download/pr/e2578737-231b-493c-a6ee-f181496fe679/18038808d2621094ebe172ca011a7c22/dotnet-sdk-8.0.100-preview.1.23115.2-linux-x64.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  180M  100  180M    0     0  67.1M      0  0:00:02  0:00:02 --:--:-- 67.1M
rich@mazama:~$ mkdir dotnet
rich@mazama:~$ tar -C dotnet/ -xf dotnet.tar.gz
rich@mazama:~$ ./dotnet/dotnet --version
8.0.100-preview.1.23115.2

Grab the dotnet/dotnet-docker repo

rich@mazama:~$ git clone https://github.com/dotnet/dotnet-docker
Cloning into 'dotnet-docker'...
remote: Enumerating objects: 87697, done.
remote: Counting objects: 100% (4692/4692), done.
remote: Compressing objects: 100% (1083/1083), done.
remote: Total 87697 (delta 1891), reused 4494 (delta 1752), pack-reused 83005
Receiving objects: 100% (87697/87697), 15.05 MiB | 24.62 MiB/s, done.
Resolving deltas: 100% (39728/39728), done.

Switch assets to .NET 8

rich@mazama:~$ cd dotnet-docker/samples/aspnetapp/
rich@mazama:~/dotnet-docker/samples/aspnetapp$ vi Dockerfile
rich@mazama:~/dotnet-docker/samples/aspnetapp$ cat Dockerfile | grep 8.0
FROM mcr.microsoft.com/dotnet/sdk:8.0-preview AS build
FROM mcr.microsoft.com/dotnet/aspnet:8.0-preview
rich@mazama:~/dotnet-docker/samples/aspnetapp$ vi aspnetapp/aspnetapp.csproj
rich@mazama:~/dotnet-docker/samples/aspnetapp$ cat aspnetapp/aspnetapp.csproj | grep 8.0
    <TargetFramework>net8.0</TargetFramework>

Build a container image

rich@mazama:~/dotnet-docker/samples/aspnetapp$ docker build --pull -t aspnetapp .
[+] Building 55.1s (15/15) FINISHED 

Run the app as root (default case)

Ports:

Note: Here, I'm running with -d since it easier for what I'm trying to demonstrate. Normally, you wouldn't do that, but use -it instead.

rich@mazama:~/dotnet-docker/samples/aspnetapp$ docker run --rm -d -p 8080:8080 aspnetapp
bd3db4a7fafda88e68d17b596c53cdb57e1c05df61aa47f6b674d5b71976277a
rich@mazama:~/dotnet-docker/samples/aspnetapp$ curl http://localhost:8080/Environment
{"runtimeVersion":".NET 8.0.0-preview.1.23110.8","osVersion":"Linux 5.15.79.1-microsoft-standard-WSL2 #1 SMP Wed Nov 23 01:01:46 UTC 2022","osArchitecture":"X64","user":"root","processorCount":16,"totalAvailableMemoryBytes":67430023168,"memoryLimit":9223372036854771712,"memoryUsage":34017280}
rich@mazama:~/dotnet-docker/samples/aspnetapp$ docker kill bd3db4a7fafda88e68d17b596c53cdb57e1c05df61aa47f6b674d5b71976277a
bd3db4a7fafda88e68d17b596c53cdb57e1c05df61aa47f6b674d5b71976277a

Run the app as app (opt-in non-root user)

rich@mazama:~/dotnet-docker/samples/aspnetapp$ docker run --rm -d -p 8080:8080 -u app aspnetapp
6b1a301e36109b0c78546f02d7f865de04f02bd6e221ff8578f5b6496d3e1fa4
rich@mazama:~/dotnet-docker/samples/aspnetapp$ curl http://localhost:8080/Environment
{"runtimeVersion":".NET 8.0.0-preview.1.23110.8","osVersion":"Linux 5.15.79.1-microsoft-standard-WSL2 #1 SMP Wed Nov 23 01:01:46 UTC 2022","osArchitecture":"X64","user":"app","processorCount":16,"totalAvailableMemoryBytes":67430023168,"memoryLimit":9223372036854771712,"memoryUsage":31543296}
rich@mazama:~/dotnet-docker/samples/aspnetapp$ docker kill 6b1a301e36109b0c78546f02d7f865de04f02bd6e221ff8578f5b6496d3e1fa4
6b1a301e36109b0c78546f02d7f865de04f02bd6e221ff8578f5b6496d3e1fa4

Switch back to port 80

This pattern only works reliably with root. In some scenarios, non-root users are allowed to listen on port 80, too. It depends on the rules of the given environment.

rich@mazama:~/dotnet-docker/samples/aspnetapp$ docker run --rm -d -e ASPNETCORE_HTTP_PORTS=80 -p 8080:80 aspnetapp
9249068c141363d83c22ee14e37f75567980109a199af67376eee532bba43632
rich@mazama:~/dotnet-docker/samples/aspnetapp$ curl http://localhost:8080/Environment
{"runtimeVersion":".NET 8.0.0-preview.1.23110.8","osVersion":"Linux 5.15.79.1-microsoft-standard-WSL2 #1 SMP Wed Nov 23 01:01:46 UTC 2022","osArchitecture":"X64","user":"root","processorCount":16,"totalAvailableMemoryBytes":67430023168,"memoryLimit":9223372036854771712,"memoryUsage":31428608}
rich@mazama:~/dotnet-docker/samples/aspnetapp$ docker kill 9249068c141363d83c22ee14e37f75567980109a199af67376eee532bba43632
9249068c141363d83c22ee14e37f75567980109a199af67376eee532bba43632
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment