Docker containers are the buzzword these days. Container technology offers a new, easy and simplified approach to deploy apps. Containers provide good degree of isolation, yet offers the luxury of leveraging host system’s hardware efficiently. If you are very new to containers, head to Docker site and get a hang on how containers work. In this post, I will show how we can build an image using dotnet core that runs on a docker container.
Docker images are primarily linux based ones. So, whatever image we build using dot net core will be running on a linux platform. Since dotnet core is a truly cross platform framework, we now have the ability to run them on docker containers. That said, we can use docker engine on Windows/macOS/Linux based systems to build the image. I will be using Docker for Mac to build images and run the containers.
Step 1 : Install Docker for Windows/Mac/Linux
Depending on your machine, you can follow the instructions from Docker site to install the appropriate component.
- Docker for Mac – https://docs.docker.com/docker-for-mac/
- Docker for Windows – https://docs.docker.com/docker-for-windows/
- Docker for Linux – https://docs.docker.com/engine/getstarted/linux_install_help/
Once the installation is complete, the docker documentation provides detailed guidelines on verifying the installation and using common commands.
Step 2 : Create a new dot net core app
Creating a new dot net core app is as easy as running the command
dotnet new . This should create a project with two files
Program.cs– containing the entry point to the app
Project.json– containing the application metadata
To make sure the application is running fine, do a
dotnet restore – to restore the dependent packages and
dotnet run – to execute the app, you should be seeing
Hello World!as the output.
Step 3 : Add a Dockerfile
Docker engine understands the instructions in this file and use them to build the image. There are a few built in commands that we can use in our dockerfile. Note that the file name should be
dockerfilewithout any extension. All we need are the below 4 lines to build the image.
COPY /app /app
ENTRYPOINT dotnet hwapp.dll
FROM microsoft/dotnet:latest – indicates that the current image we are building has to be built on top of the existing image “microsoft/dotnet:latest” (i.e, based on the latest version of dotnet image from Microsoft)
WORKDIR /app – indicates the working directory for this app.
COPY /app /app – indicates to copy the /app folder from the current application in the context to the /app folder within the image.
ENTRYPOINT dotnet hwapp.dll – indicates the entrypoint for this image, i.e, what should get executed when someone runs this image. This would make sure the app when run in a docker container produces the same output as it does when ran via
Now that we have the instructions in place, its time to run the commands and build the image.
Step 4 : Build the image
This requires some series of command execution. First is to get the “/app” directory within the application directory. That can be done by using
publish command of
dotnet cli. Run the below two commands (from the root directory of the project) to create the app directory
dotnet build dotnet publish -c release -o app
Though this can be accomplished by simply running the publish command alone, as that does the build internally. Now that app folder is available, we can run the docker command and build the image.
docker build -t hello-world-core .
-t is to specify the tag for this image and
. specifies the current context from where the dockerfile can be found. The output of the command should look like below:
Sending build context to Docker daemon 368.1 kB Step 1 : FROM microsoft/dotnet:latest latest: Pulling from microsoft/dotnet 6a5a5368e0c2: Pull complete 7b9457ec39de: Pull complete ff18e19c2db4: Pull complete 7b5d77df24dd: Pull complete aa048ddaaa8f: Pull complete 7b2ee6d027e6: Pull complete Digest: sha256:40a4e8cc6192ce04ab6c0c8f1888798a46690fb42890b0eec28cde2489e7d709 Status: Downloaded newer image for microsoft/dotnet:latest ---> 9037d65411f1 Step 2 : COPY /app /app ---> 876b56f26a66 Removing intermediate container 1be62bbdac0b Step 3 : WORKDIR /app ---> Running in dc7c513f212e ---> 6397a85eac27 Removing intermediate container dc7c513f212e Step 4 : ENTRYPOINT dotnet hwapp.dll ---> Running in a8e9a8adcca3 ---> 96908e147c78 Removing intermediate container a8e9a8adcca3 Successfully built 96908e147c78
To make sure image is successfully built, you can run the below command
docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world-core latest 96908e147c78 About a minute ago 541.8 MB
Step 5 : Run the application in container
To run the application, execute the below command
docker run hello-world-core Hello World!
Hurray! we just built and deployed our app into a docker container 🙂 What this command has actually done is
- Instanced a new container with the image “hello-world-core”
- Ran the application specified as entry point in the image.
- Torn down the container after execution
i.e, Within my Mac machine, docker created a linux based container that booted the linux system, ran the dotnet core app hello-world, and tore it down. All of these happened within seconds! That’s the power of containers! This definitely opens up a lot of opportunities for us to get more efficient with the CI/CD, scaling the app etc., More on those in a future post!