NOTE: This post is part 3 of a series on developing and deploying cross-platform web apps with ASP.NET 5:
- Develop and Deploy ASP.NET 5 Apps on Mac OS X
- Develop and Deploy ASP.NET 5 Apps on Linux
- Deploy ASP.NET 5 Apps to Docker on Linux (this post)
- Deploy ASP.NET 5 Apps to Docker on Azure
Download instructions and code for this post here: https://github.com/tonysneed/Deploy-AspNet5-Docker.
Docker is a technology for Linux that enables you to deploy applications inside of containers, which are analogous to virtual machines, but which are much more lightweight because multiple containers on a VM all share the same operating system and kernel.
While lightweight containers are a cool idea, what makes Docker a killer app is that docker images are built from a simple script, called a DockerFile, that can be layered on top of other definitions and which lists all the components needed to run your application. Images based on a Dockerfile can be pushed to an online repository called Docker Hub, where they can be built automatically whenever commits are pushed to a linked repository on GitHub. And it’s super easy to pull images from Docker Hub and run them on a Linux virtual machine, either locally or in the cloud.
In this post I’ll describe how to deploy an ASP.NET 5 app to a docker container running on a local virtual machine with Linux Ubuntu. Note that you’re not actually going to install ASP.NET 5 directly on the virtual machine. Instead, you’ll build a docker image that already comes with ASP.NET 5. Virtualization software, such as Parallels, allows you to create a number of snapshots, so that you can easily revert the VM to an earlier state.
First you’ll need to install Docker on your Ubuntu VM. We’ll install it from its own package source. Just open a Terminal and paste the following commands, one by one.
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
sudo sh -c "echo deb https://get.docker.com/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
sudo apt-get update
sudo apt-get install lxc-docker
To verify the Docker installation, enter: docker –version. You should see the Docker version and build number.
For convenience you’ll want to set things up so you don’t have to prefix docker commands with sudo for elevated privileges.
sudo groupadd docker
sudo gpasswd -a parallels docker
sudo service docker restart
To verify docker root privileges enter: docker run –help. Then just to be sure all is well, you can run the docker hello-world image, which will pull down and run a basic image from Docker Hub.
docker run hello-world
You should see the following output in the Terminal.
You can then “dockerize” the Hello World ASP.NET 5 console app. Start by creating a ConsoleApp directory and placing there two file from the AspNet Console sample repo on GitHub: project.json and program.cs. In this same directory, create a file called DockerFile, with the following content:
COPY . /app
RUN ["dnu", "restore"]
ENTRYPOINT ["dnx", ".", "run"]
This will create a new Docker image based on the AspNet 1.0.0-beta4 image on Docker Hub, which will copy files in the current folder to an app folder in the container. When the container is built, the dnu restore command will download required dependencies. The entry point is defined as dnx . run, which will invoke the code in Program.Main when the container is run.
Open a Terminal at the ConsoleApp directory and execute the following command (remember to include the trailing dot):
docker build -t consoleapp .
You can verify that the container exists by entering: docker images.
Lastly, run the container. You should see “Hello World” printed to the Terminal window.
docker run -t consoleapp
Console apps are well-suited for running tasks on a server, but more often you’ll use ASP.NET 5 to run web apps. The AspNet repo on GitHub has a HelloWeb sample, where you can grab two files: project.json and startup.cs.
Create a directory called WebApp containing these two files, as well as an empty directory called wwwroot, then add a file called Dockerfile with the following content:
COPY . /app
RUN ["dnu", "restore"]
ENTRYPOINT ["dnx", ".", "kestrel"]
Open a terminal at the WebApp directory and build the docker image.
docker build -t webapp .
Then run the container, indicating with the –d switch that you want a daemonized app running in the background that does not interact with the Terminal. You’re also mapping the VM’s port 5004 to that of the container.
docker run -t -d -p 5004:5004 webapp
This will execute the container entry point, which is to start the Kestrel web server on the indicated port. You’ll get back a container id, a big long number which you can use to see the log output. This will display log messages, including runtime error information. You can also verify that the container successfully started by entering docker ps, which lists running containers.
Open a browser and enter the address: http://localhost:5004.
And that is how you can deploy ASP.NET 5 apps to docker containers on a Linux virtual machine. For the next part of this series, I’ll show you how you can push your image to Docker Hub, where it can be pulled into a Linux virtual machine you’ve provisioned on Microsoft Azure.
The first Dockerfile to be created you asked to be named DockerFile. Need to change that capitalisation.
I receive the following error on Build:
/home/rob/Source/ConsoleApp# docker build -t consoleapp .
Sending build context to Docker daemon 46.59 kB
Step 1 : FROM microsoft/aspnet:1.0.0-beta4
Pulling repository docker.io/microsoft/aspnet
Error while pulling image: Get https://index.docker.io/v1/repositories/microsoft/aspnet/images: dial tcp: lookup index.docker.io: no DNS servers
Thanks, I’ll look into it.
I love the new functionality! Thanks for a great series of posts about the new multi platform capabilties.
I used the tools at https://visualstudiogallery.msdn.microsoft.com/0f5b2caa-ea00-41c8-b8a2-058c7da0b3e4 to do this job. I followed the step as http://www.hanselman.com/blog/PublishingAnASPNET5AppToDockerOnLinuxWithVisualStudio.aspx. But I found that the Dockerfile is different from yours. Why? Should I change mine? As sometimes Validate Connection failed. See https://www.flickr.com/photos/67801243@N06/?
ADD . /app