In the past we often had some software (e.g. web application inside an application server) that needed to be deployed on multiple servers, different stages (development, staging, production) and even on some machines hosted by a customer, but managed by ourselves.
To help with setting up the server and configuring the software, the container management tool Docker made a lot of this tasks easier by providing a defined and stable platform for application deployments.
The purpose of Docker
So, what are the aims of Docker and how can it help your deployment?
First of all, when you try to install and deploy your software on a linux server, there are a lot of uncertainties and variable conditions, that can influence your installation:
- Used operation system distribution (CentOS, Ubuntu, Debian, or even Gentoo?)
- Installed libraries and version of the libraries and tools (is java environment available? in which version by which provider in which path?)
- System settings, like character set and time zone
- Blocked ports by other services (is port 80 already taken? how to handle another server software, that also needs this port?)
- Users, Groups, Permissions
- Environment variables
So, how does Docker help to resolve this?
Docker can provide and run multiple “containers”, which are basically defined environments designed to each run one specific application. It works a bit like virtualization:
- You start with a basic operating system distribution of your choice (e.g. Debian Jessie server), or some pre-defined image (like a template for containers)
- You configure the system environment, add users, add groups
- All tools and libraries required for your software can be installed (e.g. by the normal package manager of the OS, or by just adding a tarball with the binaries)
- You start the container, by running a process with your application inside the container
- The software run inside the container can only see the operating system, files and services inside the Docker container (like a chroot)
- The container can be stopped and started again without losing anything (but it has to be stopped and started again, like a system restart, and cannot be paused like in real virtualizations, yet)
- The container has a virtual private network, which allows the software to listen to ports already bound by the host system. Those serviced can be redirected in the host system to any available port on the host network interface (e.g. you can have three docker containers with an HTTP server listening on port 80, and the host system can choose to bind one of them to its own port 80, bind one to port 8080 and ignore the third one)
- You can mount files and/or directories to paths inside the Docker container. This way, you can provide file data to the Docker container from the outside, or even take the data from inside a container to the host, e.g. for backups
- Once a program runs inside a container, you can take a snapshot from this container, move it to another host (with probably totally different OS and settings), and restart it (the container will recognize the exactly same file strcutre than before. This way you can easily change machines, or provide fallback systems
In contrast to real virtualization (like with Xen), the executed program code is not emulated, but run under the actual same kernel that runs the host system. Also the execute processes are real linux processes, that caqn even be seen on tools like top, or terminated from the host.
The Docker service uses some modern Linux kernel features, that allow for this isolation while running processes. The processes themselves are protected by the “kernel namespace” feature, which creates a new process tree which can’t access the parent processes. So inside a Docker container you can’t see or accidentally stop other processes. The Docker service also creates a network bridge, which allows the container to use the network of the host (e.g. to download files from the web), but doesn’t block ports of the host network. And last but not least, the filesystem of each container is mounted inside some Docker subdirectory, to which the container processes are then restricted, so they don’t influence each other’s file systems.