Scott Hanselman

Brainstorming development workflows with Docker, Kitematic, VirtualBox, Azure, ASP.NET, and Visual Studio

December 4, '15 Comments [23] Posted in ASP.NET | Open Source
Sponsored By

Kitematic for WindowsFirst, a disclaimer. I have no idea what I'm talking about. I'm learning and exploring some ideas, and I wanted to see what the development process looks like today (December 2015) with Docker, ASP.NET, and Visual Studio on my Windows 10 machine. I'm also interested in your ideas in the comments, and I'll share them directly with the folks who are working on making Docker integration with Visual Studio.

This post uses the bits and stuff and hacks that are working today. Some of this is alpha, some is hacky, but it's all very interesting. What do you think?

Setting up Docker on Windows

I got a new laptop and needed to set it up. This seemed like a good to time re-discover Docker on Windows.

  • For this ASP.NET-centric example, I'm assuming you have Windows with Visual Studio, but you can get Visual Studio 2015 Community for free if you need it. You'll want ASP.NET 5 RC1 as well.
  • Go to https://www.docker.com, click Get Started, then Windows. You'll end up here: http://docs.docker.com/windows/started/.
    • Note, you'll need hardware virtualization enabled in your systems BIOs, and if you are already running HyperV, either turn it off (I just to go Windows Features and uncheck it. It can be quickly turned back on later) or create a boot menu to switch between Hyper-V and VirtualBox.
    • The Docker website could get to the point faster, but they are making sure you're prepped for success.
  • Download Docker Toolbox which has a great chained installer that includes:
    • Docker Client - This is the "docker" windows command you'll use at the command line, if you want to.
    • Docker Machine - Docker Machine creates Docker hosts anywhere and configures Docker to talk to those machines.
    • Docker Compose - This is a tool for defining multi-container Docker applications.
    • Docker Kitematic - Kitematic is really accessible. It's the Docker GUI and runs on Mac and Windows.
      • I like to think of Docker Kitematic as "GitHub for Windows for Docker." Just as GitHub for Windows is an attractive and functional GUI for 80% of the things you'd want to do with Git, then Kitematic is the same for Docker. I personally think that while Kitematic is in alpha, it will be the thing that gets new people using Docker. It definitely made onboarding more comfortable for me.
    • VirtualBox - Oracles free and excellent Virtual Machine software. I use this instead of Hyper-V on the client. Hyper-V is great on the server or in the cloud, but it's not optimized for client software development or running Ubuntu VMs and remoting into them. Also, VirtualBox is extremely easy to automate, and Docker and Kitematic will be automating creating the VMs for you.

When you run Kitematic the first time it will automate VirtualBox and use a "boot2docker.iso" to boot up a new that will host your Docker containers.

VirtualBox

If you want to test things, click New in Kitematic and search for "Ghost." Kitematic will download the Dockerfile, create a VM and Container, provision everything, and run Ghost inside Docker within your (hidden from view) VM. Click Settings and you can see what port it's running on, or just click the Arrow next to Web Preview and Kitematic will launch a web browser talking to the node.js-based Ghost Blog running in Docker.

Note: Microsoft Edge is having some troubles talking to VirtualBox virtual network adapters, and I'm tracking workarounds here. Other browsers are fine.

Kitematic publishig Ghost

ASP.NET 5 and Linux and Docker

ASP.NET 5 and the .NET Core CLR are both open source and run on Windows, Mac, and Linux. We're going to make an ASP.NET in Visual Studio and deploy it to a Linux Container via Docker. The "Dockerfile" that describes ASP.NET 5 is open source and is here on GitHub https://github.com/aspnet/aspnet-docker but you don't really need to sweat that even if it is interesting.

NOTE: You can get and install ASP.NET here http://get.asp.net. Visit it from any OS and it will give you the details you need to install and get started.

An example Dockerfile for your basic ASP.NET 5 application would look like this:

FROM microsoft/aspnet:1.0.0-rc1-final

ADD . /app

WORKDIR /app/approot

ENTRYPOINT ["./web"]

It says, "start from this base docker file, add the files in . to ./app, and we'll be running from /app/approot. Then run ./web."

Deploy to Docker from within Visual Studio

The Visual Studio 2015 Tools for Docker are just a Preview, but they are pretty useful even in their Alpha state. Install them in Visual Studio 2015 - it just takes a second.

Make a new ASP.NET application with File | New Project. I made one without authentication.

Go into the Project.json and change this line to include the --server.urls bit. The important part is the *, otherwise the Kestrel web server will only listen for localhost and we want it to listen everywhere:

"commands": {
"web": "Microsoft.AspNet.Server.Kestrel --server.urls http://*:5000"
}

Right Click Solution Explorer and click Publish and you should see this:

Docker Tools for Visual Studio

From here, select Docker, and you will have a change to make a VM in Azure or publish to an existing VM.

Instead, click "Custom Docker Host" because we are going to public to our local VM.

Here's what my settings look like. Yours will be different.

Custom Docker Profile in Visual Studio

In order to get the settings YOU need, go to Kitematic and click Docker CLI to get a cool PowerShell preconfigured command prompt all setup with knowledge of your system.

Type "docker-machine config default" and you'll get a command line showing where your certs are and the IP and port of your Docker setup.

Note the result is missing a carriage return there after the port 2376.

docker-machine config default

Fill out the form with the Server Url, and image name, and some ports. I mapped port 5000 inside the container because I'll have the ASP.NET Kestrel web server listening on Port 5000.

Here's what my "Auth Options" text box looks like. Your paths will be different.

--tlsverify 
--tlscacert=C:\Users\scott\.docker\machine\machines\default\ca.pem
--tlskey=C:\Users\scott\.docker\machine\machines\default\server-key.pem
--tlscert=C:\Users\scott\.docker\machine\machines\default\server.pem

Click Validate Connection and you'll hopefully get a green checkbox.

WEIRD BUG: As of this writing the November 2015 version of the preview Docker Tools for Visual Studio 2015 has a bug when publishing to a custom host. The generated .ps1 in the PublishProfile is wrong. I think they'll fix it ASAP but the fix is to fake publish a Hello World ASP.NET project to a Docker container in any Azure VM and grab the .ps1 it generates. You don't need to hit publish, the file gets generated when you hit Next. Copy that file off somewhere and copy it OVER the wrong one in your actual project. You only have to do this once. I'm sure it will get fixed soon. You can confirm you have the right .ps1 because it'll say "Docker" at the top of the file.

image

When you hit publish, the project will build locally, and deploy into a new Docker container. You can watch Kitematic update as the deploy happens. The selected Container there is ASP.NET, and I know it worked because Kitematic puts a nice Web Preview there as well!

ASP.NET 5 in Docker in Kitematic

Brainstorming Improvements

So this is what I was able to do with existing bits. What I'd like to see is:

  • Press Ctrl-F5 in Visual Studio and have it build the project, deploy to Docker, and launch the browser all in one go. Do you agree?
    • I was thinking to make a "docker" command in the ASP.NET 5 "launchSettings.json" which would appear like this in Visual Studio.
      Docker in VS
  • Today you have to delete the container manually in Kitematic and publish again. How would you want things to work?
  • If Docker is promoting Kitematic as the best way to get started with Docker, should Visual Studio plugins know that Kitematic and Docker Machine are there and auto-configure things?

Additionally, when  Windows Containers happens, Visual Studio should clearly be able to publish an ASP.NET 5 application to the container, but even better, if this Docker flow works cleanly, I should be able to publish via Docker to Linux OR Windows from the same dialog in VS. Then after a local deployment to Docker I could Right-Click Publish and publish to Docker in an Azure VM and or Azure Container Service.

IMHO given an ASP.NET 5 app, you should be able to:

  • Publish to a folder
  • Publish to a Docker container (Linux or Windows)
    • Ctrl-F5 build AND F5 debug that container.
    • Publish to Docker in any cloud
  • Publish to an Azure VM, Web Site (App Service), or Docker within Azure Container Service
  • Editor support and syntax highlighting for Dockerfiles and Docker Compose files.
  • Docker Tools for VS should make a basic Dockerfile if one doesn't exist
  • Run xUnit and tests in the Docker Container

What do you think, Dear Reader? How much Visual should Visual Studio have? I personally like these lightweight dialogs that launch command line tools. How do you expect Docker to integrate with Visual Studio?


Sponsor: Big thanks to Infragistics for sponsoring the feed this week. Responsive web design on any browser, any platform and any device with Infragistics jQuery/HTML5 Controls.  Get super-charged performance with the world’s fastest HTML5 Grid - Download for free now!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Friday, December 04, 2015 10:35:28 AM UTC
It's been a while since I tried to run Docker on Windows and I'm really pleased with how things are working. Kitematic is very easy to use and I was up and running in only a couple of minutes. Really nice.

It would be nice if the Kitematic/Virtual Box situation would not be a Custom Host but just one of the default options.

BTW, I didn't have to copy publish to Azure PowerShell. Everything just worked out of the box.
Friday, December 04, 2015 11:03:37 AM UTC
Hi Scott,
thank you for this post, all you described or proposed is fine. I want to add about the debugging experience inside a docker / windows container for example for the ASP.NET 5 app, it'll be nice (or necessary ) to remote debug on Linux / Windows container.

Best regards, Niki
Nikolay Popov
Friday, December 04, 2015 11:04:26 AM UTC
Adding the following line to the CustomDockerProfile.pubxml removes the container before publishing again:

<DockerRemoveConflictingContainers>true</DockerRemoveConflictingContainers>

Now you don't have to remove the container from Kitematic manually.
Friday, December 04, 2015 11:57:35 AM UTC
Hi Scott,

you have a typo:

Instead, click "Custom Docker Host" because we are going to public to our local VM.

Probably meant:

Instead, click "Custom Docker Host" because we are going to publish to our local VM.

Regards,
avidenic
Friday, December 04, 2015 3:03:46 PM UTC
>Just as GitHub for Windows is an attractive and functional GUI for 80% of the things you'd want to do with Git

Ah... did you mean to say SourceTree?
Matthew Henry
Friday, December 04, 2015 4:27:16 PM UTC
I agree that this is the ultimate goal - "Additionally, when Windows Containers happens, Visual Studio should clearly be able to publish an ASP.NET 5 application to the container, but even better, if this Docker flow works cleanly, I should be able to publish via Docker to Linux OR Windows from the same dialog in VS. Then after a local deployment to Docker I could Right-Click Publish and publish to Docker in an Azure VM and or Azure Container Service."

I have tinkered with Docker, but for me the bulk (if not all) of what I do involves Windows (not Linux) so I am anxiously awaiting Windows containers. #BetterLateThanNever
Jeremy
Friday, December 04, 2015 5:27:04 PM UTC
Attempting to run this stuff behind a corporate firewall is poorly documented and difficult to get setup. I still haven't got Kitematic to work. And I haven't even got through the Docker tutorial because while setting the Docker machine proxy works to get it to download packages, some of those packages have to be configured for the proxy and fail to initialize.

All in all very frustrating.
Mike M.
Friday, December 04, 2015 9:44:10 PM UTC
It should add
<DockerRemoveConflictingContainers>true</DockerRemoveConflictingContainers>
IMHO as default.
Remote debugging needed.
No need to update ps1 file - works fine with default.
In general... this is amazing.
Thank you for great post as always.
Maciej Lelito
Saturday, December 05, 2015 12:04:55 AM UTC
@Jeremy

https://msdn.microsoft.com/virtualization/windowscontainers/quick_start/manage_docker
Mountain Whale
Saturday, December 05, 2015 3:27:24 PM UTC
From development workflow perspective, I think that the main missing piece is remote debugging.

Docker containers and the new light-weight ASP.NET (CoreCLR, DNX and Kestrel) are a great platform for developing microservice-based applications.

However, developing your services outside of the container (which includes step-through debugging) and then deploying them to a container as an afterthought breaks the natural workflow.

One of the best parts of the Docker story is that the dev and deployment environments are the same.
Vassil K.
Saturday, December 05, 2015 6:03:12 PM UTC
Thank you for this detailed article. Now, if only containers for Windows would be easier to use. My experiments with Windows Server 2016 TP3 and TP4 have been, let's say ...sub-optimal... at best.
Gabriel Schenker
Sunday, December 06, 2015 1:02:08 PM UTC
Thanks for the great article Scott.

I managed to publish but my site didn't get served up - although the endpoint seemed to be reachable.

Looking forward to more posts on this topic! :-)

Darren Neimke
Sunday, December 06, 2015 2:56:31 PM UTC
The biggest frustration my team has with working with docker and c# is the huge number of times that mono, and even the coreclr behaves differently to .net on windows.

The problem could be alleviated if we ran the software and tested it the way it will run in production. I.e in docker, with mono or the coreclr and on Linux.

Don't get me wrong, we don't discover these issues in production, we discover them on the build server, but they're still a pain to resolve.

Your suggestion of ctrl+f5 to run in docker+mono/coreclr would definitely help (the reason we run it on windows/.net is certainly because it is easier), but it doesn't go far enough.

We would really need the tests to execute under docker and debugging would be a life saver.

For the record, some of the differences we have encountered are things like different error messages being returned by the httpclient (a problem when tests are asserting on this), different error messages returned from validation attributes (I have submitted a pull request to mono and this will be fixed in the next release) and different performance characteristics. I've also submitted bug reports to coreclr and they've been fixed too.

Overall the story of c#/linux is looking good, and we'll get there, but until then, debugging and ctrl+f5 in the docker container from VS would be awesome.
Martin
Sunday, December 06, 2015 3:13:20 PM UTC
Forgot to mention (for anyone reading these comments) that the coreclr team have been incredible in fixing the bugs I have reported very quickly and the mono team have been pretty good too.

In my opinion, it won't be long before running your app on windows works exactly the same as running it on linux/docker in which case there may not be any/much use in this tooling at all
Martin
Monday, December 07, 2015 2:29:46 PM UTC
I've always been a bit confused why anyone would want to publish. "Publish" to me means git push. In terms of working locally with containers, I'd rather just use a docker volume to map to the source directory.
Jon
Monday, December 07, 2015 8:19:27 PM UTC
Hey folks,
I just wanted to respond with a few things. First, we are working on an inner loop F5 experience. Not just as a way to cover gaps in the Linux/Windows implementation, but because they're are platform specific libraries. We want developers to catch these immediately, not later in their development cycle.
As Gabriel pointed out, we do have Windows Container support in the Docker Tools for VS. http://blogs.msdn.com/b/stevelasker/archive/2015/08/24/windows-container-video-series.aspx And, you can setup your project to publish to both Windows and Linux. http://blogs.msdn.com/b/stevelasker/archive/2015/08/24/deploying-to-linux-amp-windows-docker-containers.aspx
That said, we completely agree that the current publish experience is a great way to get started, but not the optimal solution. We are working on a Container project that will provide:
F5 & CTRL+F5 that leverages Debug/Release modes
Compose to support multiple container images, multiple environments and multiple configurations
Ability to change how images are created, labeled, etc, by using Powershell scripts on Windows and bash scripts on Mac.
For some insights to the work, look at http://aka.ms/yodocker. We've been engaging with the Linux and startup community as well as some key enterprise customers that are already using Docker in production to understand the challenges developers have further down the learning to execution cycle. We want to set developers up for success with their first experience, while balancing the number of concepts you need to learn to get started, without having to toss out the learnings when you get serious about your team development.
So, please keep the feedback coming, and we'll share out the new experiences we're targeting shortly.
Thanks to Scott for the nudge and your thoughts,
Steve
Tuesday, December 08, 2015 9:02:54 PM UTC
"docker-machine config default" would have saved me a couple hours over Turkey day weekend. Also, updating the docker/kitematic toolchain gets ugly fast. boot2docker.iso is stored in 3 different locations on a Windows box. I had to update it manually to get around a client-server api version missmatch.
Steve
Wednesday, December 09, 2015 2:27:31 PM UTC
I don't know, if this is the right place or not.
Can we have signalR project hosted in a docker container?
Vinay
Thursday, December 10, 2015 11:36:55 AM UTC
I hope to have same experience on Windows containers. I've been following the Windows container samples on MSDN, so far it took several hours to prepare a base environment(install ServerCore2016, configure Docker etc). I wish it to be as fast as Docker on Linux.
Gokhan Demir
Thursday, December 10, 2015 2:12:47 PM UTC
I am ASP.NET beginner, so thank you for this info.
Monday, December 14, 2015 7:48:22 PM UTC
Docker will be a serious contender on Windows once they support Hyper-V. Hyper-V can be automated easily enough (see the Visual Studio Emulator for Android); even Vagrant supports it. I've seen rumors of support down-the-line for runnging Windows as the OS within containers - that's when things will truly get interesting!

Virtual Box's strength is that it is cross-platform + free (if you download it yourself); it's focus on client virtualization starts off mis-aligned with ASP.NET (server-side) development. Add on the issues that begin to pile one once more than one developer is involved (orchestration of testing, etc.) and Virtual Box quickly falls into the "more pain than gain" category.

Thanks for documenting how the sausage is currently being made, what a mess!
Jed
Sunday, January 24, 2016 6:11:09 PM UTC
You always need to improve yourself. This is great resource to do this: https://examrange.com
Scot
Thursday, February 11, 2016 11:03:50 PM UTC
In case anyone's publish failed with the following error:

---START OF ERROR---
Error: An error occured during publish.

The command [docker --tlsverify --tlscacert="C:\\Users\\bla\\.docker\\machine\\certs\\ca.pem" --tlscert="C:\\Users\\bla\\.docker\\machine\\certs\\cert.pem" --tlskey="C:\\Users\\bla\\.docker\\machine\\certs\\key.pem" -H tcp://192.168.99.100:2376 build -t devwkflowtest -f "C:\Users\bla\AppData\Local\Temp\PublishTemp\zapp29\approot\src\zapp\Properties\PublishProfiles\v" "C:\Users\bla\AppData\Local\Temp\PublishTemp\zapp29"] exited with code [1]: unable to process Dockerfile: read C:\Users\bla\AppData\Local\Temp\PublishTemp\zapp29\approot\src\zapp\Properties\PublishProfiles\v: The handle is invalid.
---END OF ERROR---

I posted a solution at https://stackoverflow.com/questions/35351528/visual-studio-publish-to-custom-docker-container-fails-due-to-non-existent-direc.
Robert Tassarone
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.