In this post we are going to look at Docker with .Net core and the reasons to utilize docker for deployment of AspNet core applications.
First of all we will look at what docker is essentially, what problems it solves and what one needs to know to get started with docker containerization.
What this post will cover
- What is docker
- Which problems does docker solve with application deployment.
- Why use docker
What this post will not cover
- How to create docker containers and images
- How to compose docker containers
- How to manage docker container lifecycle
What is docker
Docker is a container technology.
To understand what this means, we will look at what problem a container solves and where the idea comes from.
We will then see what a container is, how it is different to technologies like virtual machines and how one uses it effectively.
Essentially what docker does, sounds on the first hearing like what a VM does:
It isolates different environments against the OS and other applications to ensure that you’ll have always almost the same environment on any machine to match your anticipated production environment.
The biggest difference to a VM is that docker does not host a complete virtual OS but instead uses the underlying OS for low level functionality like file system access, kernel activity, access to the network stack and so on and so forth.
This has as a result that you need the OS which runs your application to support your application and vice versa. So although you can use docker on Windows, if you want to use Linux containers (which are much more mature) you will need a technology that supports Linux OS.
Luckily for us, the reworked dotnet core development platform supports Linux OS very well.
A docker container creates an isolated area for your application where everything is supplied for the application to work in the expected way.
In context of AspNet core applications this means the binaries as well as the dotnet runtime and every third party library you might need.
Why use docker
Docker supplies a set of tools for container technology development and works on Windows as well as on Linux.
As mentioned in the intro, we want to explore why one might want to use a container technology like docker. This is because it helps to solve two important problems:
The first problem docker solves ist the so called consistency problem also known as the “works on my machine” problem.
The second issue which it helps to tackle is the responsiveness problem which deals with the concepts of horizontal vs. vertical scaling.
1.) Consistency Problem
The consistency problem arises because applications are made up of many components. For example most applications are made up of components like databases, third party components, a web server or maybe more servers, probably a loadbalancer to distribute http requests, data caches and so on and so forth.
With all those moving parts, not every developer has an exact replication of the production system available at any time. Yet for good integration testing etc. you want to get as close to the production system as possible to identify issues that could harm deployment to production in any way.
If you cannot supply a system that resembles the production system in its most important parts this leads to assumptions that might not be valid in a production environment, and therefore lead to unforeseen consequences in the production system
Also deployment can be a problem, as you need two configurations (one for devolpment and one for production), where the latter one is hard to test until you really go into production. Last but not least, consistent configuration of all servers of the production system might be very time consuming and tedious.
How does docker solve this problem?
For containerization you have the need to create an (template) image, which includes the complete environment.
Everything to run the application is contained in this container.
Every container that is created from this immutable image creates an identical instance of this AspNet core mvc application.
The development environment might still be an approximation of the real production system, yet it is a far better replica. The only difference might be that the development environment has just the additional compiler and debugger.
Else it will be identical (production and dev): they have the same filesystem with same paths, the same network topology, same Nuget packages, and dotnet runtime. (At least in theory, you will still get some hurdles to cross, software development still becomes never easy, although it gets easier over time ;-).
Also all classes are compiled and dev tools will be omitted.
There is also no need to update the configuartion files, because they are identical for the most part, so a database connection strings for example will work for both environments considering all things being equal.
2.) Responsiveness problem
The second issue that docker helps to solve is the responsiveness problem.
In “classic” AspNet MVC applications that are deployed with an IIS, you often have either to much resources allocated to handle the incoming requests, or to few resources.
This often lead to the issue, that you either could not handle all incoming requests with the appropriate amount of resources. To handle more work you had to reconfigure the IIS and in some cases where you would handle much more work you would need to scale vertically by supplying newer and/or more hardware.
How does docker solve the responsiveness problem?
A container is a lightweight wrapper around an application, with just the right amount of resources to handle the expected load.
One server can run multiple containers, then scaling is just a matter of more containers!
As a contrast to the vertical scaling of a single server with a single application. More docker containers then allow for dynamic rebalancing at runtime, by adding and removing containers at runtime.
Where is the difference to VMs?
Both container and virtual machine technology are used for standardized environments, both can be used for scaling so why use containers for scaling?
Containers are no VMs.
VM provides complete isolated software stack including the OS. So e.g. you could run Windows and Linux side by side on a single server.
A container technology on the other hand only isolates the application and its immediate environment, so Linux applications only run on linux.
But because of this they need much less resources than vms. Especially because they need less resources for OS tasks, because containers simply use the provided OS on which they run.
The most important difference for AspNetCore is that containers solve the responsiveness and consistency problem in an very elegant way, which is hard to do with vms (essentially more configuration is required for vms). This is because you can set up containers quite easily with stacking images on top of each other and extending the containers functionality.
What do you need to respect with docker containers?
Containerized applications are best suited for stateless applications (only db access in containers, else each request is stateless). As for web applications this should be the ideal case in every circumstance, therefore containerization works very well for this kind of scenario.
Also your application should not need a lot of manual intervention or require manual configuration tasks, as it is not suited for MVC apps in containers (it would defeat the purpose of scaling horizontally). Also only single instance restrictions would not allow for containerization for the same reasons.
Why use docker and not another container technology?
Docker is a very mature technology, has an extensive open source platform called the DockerHub, and is widely available and ready to use. Because it is so widely in use you get a lot of images you can build on for your application
See also more on docker here:
Docker as a container technology helps to isolate your production environment of your application to ensure you have it easier to integrate your application into a production environment.
Also containerization allows you to handle the responsiveness problem in an easier way, so scaling can be done dynamically with regards to the current load.