How to Create a .NET 6.0 SDK Linux Docker Container
Tags: docker, csharp
Published: 2021-11-12 23:58:18

This post describes the steps I took to create a .NET 6.0 SDK Docker container running Ubuntu 20.04. I should note that my host machine is also running Ubuntu 20.04. Here is a more detailed explanation on how to [setup Docker .NET images on GitHub](https://github.com/dotnet/dotnet-docker/blob/main/samples/README.md).  

# Install Docker on Ubuntu 20.04
I quite like the [Docker documentation](https://docs.docker.com) on [how to install Docker on Ubuntu](https://docs.docker.com/engine/install/ubuntu/) so I am not going to repeat the steps here.

# Note the .NET 6.0 Dockerhub Image Tag
[Dockerhub](https://hub.docker.com/) is the biggest and most well-known repository of pre-built docker images. It hosts the .NET 6.0 [runtime](https://hub.docker.com/_/microsoft-dotnet-runtime) and [SDK](https://hub.docker.com/_/microsoft-dotnet-sdk) images built by Microsoft.

Say you want to install the .NET 6.0 SDK on Ubuntu 20.04.

First you need to know the path. If you look at the "Featured Tag" section of the page, you will see something like the following ...
![.NET 6.0 featured tag](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cg92zi9qbljl5qvpu39e.png)
More information on the featured tag can be found on the [samples page](https://github.com/dotnet/dotnet-docker/blob/main/samples/dotnetapp/README.md) ...
> The sdk:6.0 and runtime:6.0 tags are both multi-arch tags that will result in an image that is compatible for the given chip and OS. These simple tags (only contain a version number) are great to get started with Docker because they adapt to your environment.
They do mention that for production systems, you should specify an OS-specific tag. So we need to extract the image path from the tag. In this case, the path is "mcr.microsoft.com/dotnet/sdk".

Now if you navigate to the "Full Tag Listing" on the [.NET SDK dockerhub page](https://hub.docker.com/_/microsoft-dotnet-sdk), you will see something like the following ...
![.NET SDK dockerhub page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bivmiumlw68mzuk3r4xi.png)

Say I want the latest Ubuntu 20.04 image, then the tag will be "6.0-focal" and the full path will be "mcr.microsoft.com/dotnet/sdk:6.0-focal". But you can use any Linux image tag. For example to build an Alpine image, use "mcr.microsoft.com/dotnet/sdk:6.0-alpine".

# Create a Dockerfile
So now we know the path and tag of the image we want to base our image on, we can create a a file called "Dockerfile" in an empty directory ...
```docker
FROM mcr.microsoft.com/dotnet/sdk:6.0-focal AS build
```

# Build the Docker Image
To create the image we run the following command in the same directory as the "Dockerfile" ...
```bash
sudo docker build -t example-image .
```
The "-t" option specifies a tag name and the "." tells it which directory to find the "Dockerfile".

To see that the image has been successfully created, run ...
```bash
sudo docker image ls
```

# Create and Run a Command in a Container
To create and run a command in a new container based on the image we just built, we run the following command ...
```bash
$ sudo docker run --name example-server -it --rm example-image bash
```
The "-it" will run the bash command interactively and allocates a [pseudo TTY](https://en.wikipedia.org/wiki/Pseudoterminal) to allow us to effectively run a bash shell in our current shell. The "--rm" will automatically remove the container that gets created. If we did not use the "--rm" option, each time we run the command, a new container would be created. From the bash terminal running in the container, list out the supported SDKs and exit ...
```bash
root@2dc636974d10:/# dotnet --list-sdks
6.0.100 [/usr/share/dotnet/sdk]
root@2dc636974d10:/# exit
```
The "exit" command will exit the bash shell running in the container and the container will get deleted because of the "--rm" option we specified in the run command.