Last week was one of Microsoft’s biggest conferences, “Build”. If you didn’t go, or watch all of the content live, you can see the keynote and all of the sessions from here:
To me, it’s alarming to see how drastically and how quickly the .NET platform has been changing. In particular, ASP.NET is almost unrecognizable to what it was even a year ago! One thing that stood out to me from the Day 1 keynote was Docker.
I’ve heard many people refer to this, but didn’t bother investigating as I thought it was one of a zillion fly-by-night technologies that come and go. I’m only interested in investing time in technologies that have some “staying power”.
Well, Microsoft all-but-said that they are “all in” with Docker. So, it’s time to see what it’s all about.
What is Docker?
Docker is basically a super-thin hypervisor that runs a Linux “microkernel”, a very thin abstraction layer, which can run a Docker containerized application. Huh? Ok, with almost any programming technology, you can make “Dockerize” it, or have it run in a Docker container (like, a bubble). Then, your application bubble can run on any platform that supports Docker. What operating systems does Docker run on? All of them.
Imagine that in Visual Studio, you compile your app and then bundle it up for Docker (somehow). Your ASP.NET application will then run on ANY server that runs Docker. So, your ASP.NET application can run on Linux, Mac, Windows, etc. In the same way that Hyper-V or VMWare let you host server operating systems in “bubble”, this is similar, except at the application level.
How do you bundle your app (create a Docker “container”)?
Well first you need Visual Studio 2015 RC (as of this writing), because only ASP.NET 5 is supported (as of this writing). So, in VS2015, go into Tools –> Extensions and Updates and search for “Visual Studio 2015 RC Tools for Docker – Preview”:
When you install that, and create an ASP.NET 5 web application:
You’ll notice that if you right-click on the project and choose Publish, you’ll have a Docker option there:
you should see:
When you select Docker Containers and click Next, choose “Custom Docker Host”:
but then, uh-oh. What are we supposed to fill in, here?
Let’s go over to Ubuntu and set up that environment, next.
Installing and configuring Docker on Ubuntu Linux:
I really like Ubuntu Linux because it’s based in Debian Linux – which is one of the saner distributions of Linux, and it’s arguably the most user-friendly distribution too. What I did was grab the Ubuntu Server ISO (which is a DVD image file) from:
Then, using Hyper-V I provisioned a new, local server. For reference, I’m calling it SPHUSDCK01. From a fresh install of the operating system, I follow the instructions on the Docker website and do:
$ wget -qO- https://get.docker.com/ | sh
After a few screens of messages, I end up seeing this:
I take that advice and run the following to make it so I don’t have to constantly “sudo” docker commands:
$ sudo usermod -aG docker rseder
I then reboot:
$ sudo reboot
When I log back in, I see the current state of Docker by doing a “docker ps” and “docker images”:
So, no containers or images are setup. OK, we have a Docker installation – let’s make sure it works. Supposedly, I can run:
$ sudo docker run hello-world
and sure-enough, I see a good message:
This is all great, but we still don’t know what to put in Visual Studio!
Configuring Docker to accept network requests:
As I discovered, Docker is set to run as a process on a server and does NOT listen for requests on the network. It does support two modes though:
- HTTP: unauthenticated users can publish Docker containers (completely insecure, used for testing – and what is covered in this blog post)
- TLS: authenticated users, using keypairs, can publish Docker containers (haven’t gotten this working yet).
OK, so how to we at least get HTTP going? We have to edit the Docker configuration file, add a couple of things to it, then restart the Docker service. Edit the config file:
$ sudo nano /etc/init/docker.conf
In that file, you should find two instances of a “DOCKER_OPTS=”, like this:
change these two lines to read:
DOCKER_OPTS=’-H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock’
so that it looks like this:
Make sure you change it in both places in the file. Then CTRL+X to exit and save. Then, restart the Docker service:
$ sudo service docker restart
OK, how do we verify that worked? Well, notice that “4243” in the line we added? That is the port that the HTTP endpoint is running on. So, we can navigate to the following:
where “sphusdck01” is the name or IP address of your Ubuntu server. This is the Docker service responding back with all of the Docker images that are installed (remember “docker images” from above? This is the same result):
OK – it looks like Docker is listening on HTTP on port 4243. Hey, that seems like most of what we needed back in Visual Studio! Let’s take a look…
Publishing from Visual Studio:
Now, we can go back to that Publish screen and fill it out – and point to :
PLEASE NOTE: that the Server Url needs to be “tcp://” and won’t work with “http://”. OK, we click Publish:
this runs for a several minutes and then a browser pops open:
OK cool, bu… wait a second. What is that?? The URL is pointing to my new Ubuntu Linux server?!
My ASP.NET application is running in Docker, on my Ubuntu Linux server! If we go back to the Ubuntu server now and check on Docker:
we confirm that “webapplication1” was deployed and is running.
Well, although this technically worked – this is not how you’d normally use this. You really should publish securely. You might notice in the example above I never provided any credentials! That means that ANYONE can do anything on that Docker server, running on HTTP.
As mentioned, Docker supports TLS (https) and the ability to authenticate with key-pairs. I started going down that road but wasn’t able to get it working just yet. Once I do, I’ll likely do a blog post on it.