On the 16th May 2016 Microsoft released .NET Core RC2 which comes with a brand-new simplified CLI. .NET Core is the regular .NET framework re-thought from the ground up to be cross-platform across Windows, Linux and Mac.
On release day Docker's Mano Marks blogged showing us a .NET Core RC2 application running in Docker while being debugged through Visual Studio. In this post we take a step back and say Hello to dotnet Core RC2.
Making a start
A DNCore console application needs both a project file (project.json) and an entrypoint (Program.cs). Normally a heavy-weight IDE like Visual Studio 2013/2015 would be needed to create these template files. I'm going to show you a new CLI command:
dotnet new which feels a lot like
npm init in the Node.js space.
Generate the code through
- Make a new directory
- Run the following container making sure you update the
-vvolume mount to match your working directory. This means that whatever files the container creates in
/root/will automatically be transferred to the host machine.
$ mkdir -p hello-dncore/app $ docker run -v \ /Users/alex/hello-dncore/app:/root/ \ -it microsoft/dotnet:latest
microsoft/dotnet image will be pulled from the Docker Hub and then started.
- Change directory to
- Type in
dotnet newand exit the container.
root@a0b44ebbd8e3:/# cd /root/ root@a0b44ebbd8e3:~# dotnet new Created new C# project in /root. root@a0b44ebbd8e3:~# ls Program.cs project.json root@a0b44ebbd8e3:~# exit
On your host you will now see the files we need appear in your app folder:
Alternative: clone the repository
If you want to skip that step then you can go ahead and clone a pre-generated repository.
$ git clone https://github.com/alexellis/hello-dncore.git $ ls hello-dncore/app/ Program.cs project.json $
To run the code we need a Dockerfile.
This is the same image as before and contains the ability to both build and run DNCore applications.
This image runs as root by default which may be flagged up by container vulnerability scanners. You could also try adding a regular user at this step. From looking at
/etc/issue the image appears to be based upon Debian GNU/Linux 8 meaning the
adduser utility could be used.
ADD ./app/ /app/
Add the Project.cs file and project.json into the image.
RUN dotnet restore
This step downloads all the dependencies and libraries required to make your application run. It will output a lot of text and download around half a gigabyte of files.
RUN dotnet build
At this point we could use
dotnet run which invokes a build but I've chosen to build beforehand so that the container will start quicker.
CMD ["dotnet", "run"]
And finally we have the entrypoint or CMD to the container itself. This will execute the .NET code which was built in the previous step.
Here is a summary of the Dockerfile
FROM microsoft/dotnet:latest WORKDIR /root/ ADD ./app/ ./app/ WORKDIR /root/app/ RUN dotnet restore RUN dotnet build CMD ["dotnet", "run"]
- Build the docker image
docker build -t hello-dotnet .
- Run the image:
docker run -ti hello-dotnet
Program.cs to change the
Console.WriteLine message. After each edit repeat the
docker build/run steps.
Here is what I got from my test-run of the container.
$ docker run -ti hello-dotnet Project app (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation. Hello World!
If you want to skip straight to this step you can pull my container from
As you may have noticed the
dotnet restore step takes a while to download everything needed. I found that
dotnet restore alone added over 470mb of libraries. Check your image with
docker history hello-dotnet.
CREATED BY SIZE /bin/sh -c #(nop) CMD ["dotnet" "run"] 0 B /bin/sh -c dotnet build 129.6 kB /bin/sh -c dotnet restore 471.6 MB
If we add the project.json file separately from the rest of the code we could potentially benefit from Docker's layer caching.
Without having to install any runtimes or IDEs (other than Docker) we were able to:
- Create a DNCore RC2 Console Application
- Build the application and download its dependencies
- Run the application and view its output
After having played with the previous version of the CLI (dnvm dnx, dnu) I'm impressed with how simple and cohesive the new
dotnet command appears to be.
For my use-case as a .NET web developer there is still a lot of work to be done on the project before it can be a viable alternative to a full .NET framework. I'm looking forward to being able to connect to MongoDB, Redis and SQLite but it's still too new to support all of these back-ends. For a good idea of what is available check out the Official Github Repo.
In the meantime the Mono project is doing some really amazing work and can run a full cross-platform .NET version. Check out my Hands-On Docker tutorial for more on using Mono with Docker.
Have you tried the tutorial? Do you you want to share what you've built? Let's chat in the Disqus comments below.