It's early days, but this is a nice preview of the possibilities of things to come. I often use LEGO bricks in the way of an analogy when talking about software systems. I like the idea of choice, flexibility, and plug-ability. Choosing your language, operating system, deployment method and style, etc are all important.
There is a preview of an extension for Visual Studio 2015 (the release candidate at the time of this writing) that adds Docker support. If you have VS2015 RCyou can get the Docker Extension here. You can certainly manage things from the command line, but I think as you go through this post you'll appreciate the convenience of this extension.
NOTE: It's also worth pointing out that there is a Windows client command line for Docker as well. You can "choco install docker" and read about it here.
The Brief What's Docker Explanation
If you aren't familiar with Docker, here's the super basics.
- Virtual Machines: You likely know what a virtual machine is. It's the whole operating system, the whole computer, virtualized. If you have a 10 megabyte app you want to run, you may end up putting it in a 10 gigabyte virtual machine and carrying it around. That gives great security and isolation as your app is all alone on its own private VM, but it's a little overkill. Now you want to deploy 100 apps, and you've got space, CPU, and other things to think about. VMs also start slow and have to be actively maintained.
- Docker/Linux Containers (and Windows containers "Docker for Windows Server"): Containers let you share most of that 10 gigabytes of support software between lots of apps, giving you less isolation but also using a LOT fewer resources. Containers start fast and the underlying shared resources are what's maintained and kept up to date.
Docker also is a way to package up an app and push it out in a reliable and reproducible way. So you can say that Docker is a technology, but also a philosophy and a process.
Docker and Visual Studio
Once you have the Docker for Visual Studio 2015 extension (preview) installed, go ahead and make an ASP.NET 5 app. Right click the project and hit Publish.
Note the Docker Containers section that's been added? You still have PAAS (Platform as a Service) and can also publish to VMs within Azure as well. Select Docker and you'll be here:
We'll make a new VM to host our Docker stuff. This VM will have be the host for our containers. Today it'll be an Ubuntu LTS VM. Note that the dialog includes all the setup for Docker, ports, certs, etc. I could use existing VMs, of course.
If you don't have a VM, then the initial create takes a while (5-10 min or more) so hang back. If you already have one, or the one you created is ready, then march on.
Make special note of the Dockerfile option. You'll usually want to select your own manually created Dockerfile, assuming you're doing more than just a Hello World like I am.
The ASP.NET Dockerfile is up on GitHub: https://github.com/aspnet/aspnet-docker and in the Docker registry: https://registry.hub.docker.com/u/microsoft/aspnet/
In the build window you'll see lots of docker-related output. Here's a snipped version for flavor.
VERBOSE: Replacing tokens in Dockerfile: C:\Users\Scott\AppData\Local\Temp\PublishTemp\approot\src\WebApplication6\Properties\PublishProfiles\Dockerfile
VERBOSE: Package output path: C:\Users\Scott\AppData\Local\Temp\PublishTemp
VERBOSE: DockerHost: tcp://hanseldocker.cloudapp.net:2376
VERBOSE: DockerImageName: webapplication6
VERBOSE: DockerPublishHostPort: 80
VERBOSE: DockerPublishContainerPort: 80
VERBOSE: DockerAuthOptions: --tls
VERBOSE: DockerAppType: Web
VERBOSE: DockerBuildOnly: False
VERBOSE: DockerRemoveConflictingContainers: True
VERBOSE: LaunchSiteAfterPublish: True
VERBOSE: SiteUrlToLaunchAfterPublish:
VERBOSE: Querying for conflicting containers which has the same port mapped to the host...
Executing command [docker --tls -H tcp://hanseldocker.cloudapp.net:2376 ps -a | select-string -pattern ":80->" | foreach { Write-Output $_.ToString().split()[0] }]
VERBOSE: Building Docker image: webapplication6
Executing command [docker --tls -H tcp://hanseldocker.cloudapp.net:2376 build -t webapplication6 -f "C:\Users\Scott\AppData\Local\Temp\PublishTemp\approot\src\WebApplication6\Properties\PublishProfiles\Dockerfile" "C:\Users\Scott\AppData\Local\Temp\PublishTemp"]
VERBOSE: time="2015-05-27T10:59:06-07:00" level=warning msg="SECURITY WARNING: You are building a Docker image from Windows against a Linux Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories."
VERBOSE: Sending build context to Docker daemon 28.01 MB
VERBOSE: Step 0 : FROM microsoft/aspnet:vs-1.0.0-beta4
VERBOSE: vs-1.0.0-beta4: Pulling from microsoft/aspnet
VERBOSE: e5c30fef7918: Pulling fs layer
VERBOSE: e5c30fef7918: Pull complete
VERBOSE: e5c30fef7918: Already exists
VERBOSE: Digest: sha256:27fbe2377b5d4e66c4aaf3c984ef03d22afbfee3d4e78e10ff38cac7ff162d2e
VERBOSE: Status: Downloaded newer image for microsoft/aspnet:vs-1.0.0-beta4
VERBOSE: ---> e5c30fef7918
VERBOSE: Step 1 : ADD . /app
VERBOSE: ---> cf1f788321b3
VERBOSE: Removing intermediate container dd345cdcc5d9
VERBOSE: Step 2 : WORKDIR /app/approot/src/WebApplication6
VERBOSE: ---> Running in f22027140233
VERBOSE: ---> 7eabc0da4645
VERBOSE: Removing intermediate container f22027140233
VERBOSE: Step 3 : ENTRYPOINT dnx . Kestrel --server.urls http://localhost:80
VERBOSE: ---> Running in 4810324d32a5
VERBOSE: ---> e0a7ad38eb34
VERBOSE: Removing intermediate container 4810324d32a5
VERBOSE: Successfully built e0a7ad38eb34
The Docker image "webapplication6" was created successfully.
VERBOSE: Starting Docker container: webapplication6
Executing command [docker --tls -H tcp://hanseldocker.cloudapp.net:2376 run -t -d -p 80:80 webapplication6]
Docker container started with ID: 6d4820044df200e87f08cb5becbec879d1b58fcab73145ca3aa99a424c162054
To see standard output from your application, open a command line window and execute the following command:
docker --tls -H tcp://hanseldocker.cloudapp.net:2376 logs --follow 6d4820044df200e87f08cb5becbec879d1b58fcab73145ca3aa99a424c162054
VERBOSE: received -1-byte response of content type text/html; charset=utf-8
Executing command [Start-Process -FilePath "http://hanseldocker.cloudapp.net/"]
Publish completed successfully.
The interesting parts are the calls to dnx (the .NET Execution host), the warning that I started on Windows and I'm going to Linux, as well as the fact that we're using the "microsoft/aspnet" docker image.
It worked great. I'm looking forward a cross-platform cross-tools choice-filled future. Finally, there's a great 7 part video series here called "Docker for .NET Developers" that you should check out on Channel 9.
Sponsor: Big thanks to Atalasoft for sponsoring the blog and feed this week! If your company works with documents, definitely check out Atalasoft's developer tools for web & mobile viewing, capture, and transformation. They've got free trials and a remarkable support team, too.
© 2015 Scott Hanselman. All rights reserved.