A development workflow with Docker and .NET Core

I want a code editor which lets me issue commands, e.g Docker commands and has C# support like code completion and syntax high-lightning. I also want live reload when doing changes in the source code so the development loop would look something like:

  1. Write code
  2. Run the code in a Docker container
  3. Test the application running in the container
  4. Make code changes
  5. Repeat from 3

In order to restart the application when file changes occur we can use dotnet-watch. However, when mounting the volume containing the source code in a container via a virtual machine, which is the case on Windows and Mac, file changes won’t automatically be notified so we need a polling strategy. Luckily, polling has recently been added to dotnet-watch. At the time of writing this feature is not available in any official NuGet package or Docker image so the setup will be done an Ubuntu machine.

When it comes to code editors with an integrated terminal there are some options. Unfortunately Visual Studio Code doesn’t have this capability at least not yet. Atom and Sublime Text both have plugins that provide terminal like functionality but are not sufficiently capable in my opinion.

Enter Vim. With Vim you can do `Ctrl + Z` to switch to the terminal and the type `fg` to return to the editor. There’s also Omnisharp support for vim which provides syntax-highlighting, code completion etc.

So lets start building something simple, a Hello world Web API. This is thus step 1:

using System;
using Microsoft.AspNet.Mvc;
public class HelloController : Controller
    public string Start()
       return "Hello world!";


FROM microsoft/aspnet:1.0.0-rc1-update1-coreclr
COPY project.json /app/
RUN ["dnu", "restore"]
COPY . /app
RUN ["dnu", "commands", "install", "Microsoft.Dnx.Watcher"]
CMD /root/.dnx/bin/dnx-watch web

Project file

    "version": "1.0.0-*",
    "dependencies": {
        "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
        "Microsoft.AspNet.Mvc": "6.0.0-rc1-final"
    "commands": {
        "web": "Microsoft.AspNet.Server.Kestrel --server.urls http://*:5004"
    "frameworks": {
         "dnx451": { },
         "dnxcore50": { }

docker-compose file

  build: .
    - "5004:5004"
    - .:/app

From a terminal window step 2 above can now be performed:
docker-compose up -d

The d-flag executes the application in the background so that the terminal is available for further input commands.
The ip of the running container can be retrieved with:
CID=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' ) where the container Id is listed with docker ps.

Now onto step 3:
curl $CID:5004/api/hello returns “Hello World” from the API.

Let’s change the returned message from the API method (step 4):
vim HelloController.cs and change the message to “Hello brave new World!” followed by save (:w) and returning to the command line with Ctrl+Z. The changes are picked up by dnx-watch and the application is restarted with the new change.

Back at step 3 another curl call now returns “Hello brave new World!” from the API.


I personally find the workflow described here pretty straight forward but not perfect (e.g. how would you go about debugging the application inside a container?). Hopefully the editors will become more “Docker-aware” by time so that the fact that the application is running inside of a container is more or less hidden from the user.

If you have a nice development workflow with Docker to share, I’d love to hear about it!

This Post Has 4 Comments

  1. Stepan

    Hi Christian,
    thanks for you blog post.

    I found nice trick in your dockerfile with restore nuget packages:

    COPY project.json /app/
    WORKDIR /app
    RUN [“dnu”, “restore”]

    I understand why you made it.

    But in real world you have more than one project in your solution. e.g. BusinessLayer project which is used in your web mvc project. New templates of Class Library project is nuget package based project.
    So if project.json contains references on such projects from your solution – dnu restore will fail.

    Could you improve your dockerfile for such cases?

    1. Christian Jacobsen

      Hi Stepan,
      thanks for your comment.

      There really isn’t any difference between running an application locally (on the host machine) and running it in a container i.e. all commands that you would issue running the application locally equally applies in a container.

      So in the case above, if the application has dependencies to other class libraries in the solution, they will be compiled and linked through the dnu restore command as long as the corresponding code has been copied to the container.

Leave a Reply