
Docker containers
Environment-specific issues have always plagued developers and operations teams. A developer may work locally on a Windows or Mac computer, while his code may end up running on a Linux server. When promoting builds from one environment to another (test, stage, production), yet again the environment changes and leads to more possibilities of failure.
Consider a few simple cases of what can go wrong with changes in the environment:
- The file path separator used in Windows is a back slash \, while Linux requires the forward slash /
- Java version mismatch issues between environments
- Environment variables or configurations, such as datasource name or other application server settings can differ
- The OS library versions may not be the same and any dependencies on these can break the code
- The database drivers are usually part of the application server and the versions may not be in sync across environments
To overcome the environment disparity or it works on my machine conversations, solutions such as virtual machines (VM) and containers have come up to provide a consistent and portable environment. Most Java architects and developers would have come across virtual machines.
It's useful to compare a container to a virtual machine; this helps us to understand some of the key differences. Virtualisation is used for creating multiple environments based on a single physical hardware system.
Docker isn’t the same as traditional virtualisation, though there are similarities between the two, since they share some characteristics. Both provide isolation for your application and the ability to bundle the solution as a binary image. Docker provides an isolated environment called a container, which allows for packaging and running an application such as a microservice.
A VM houses not only the application, but an entire operating system with all its bells and whistles. The way you build a VM is by creating an OS image which has everything in it and can be stripped down later, based on your application needs. This is in contrast to how you work with containers. A Docker container is built by putting together the minimum software that is required for running the application.
Docker, unlike VM, is an application delivery solution which meets high scalability needs. Another aspect that is different from VMs is that your application data doesn't live within a container. Data is saved outside the container using defined volumes, which gets shared between multiple instances of a container. A container can save data to its filesystem as well; this will remain persisted until the container is deleted.
Deploying the actual container can be done on physical or virtual machines, on cloud, or on premise. Docker doesn't enforce any constraint regarding the underlying infrastructure, thus you can mix and match strategies as per your needs.
Technically, a VM requires a hypervisor which enables running multiple Guest OS's on top of the host machine. Each virtual machine will have its own operating system, along with all the libraries and applications within it. Docker, on the other hand, doesn't require the additional hypervisor layer, as it directly utilizes the host machine's kernel, making it lightweight and incredibly fast to start and stop. VMs are usually gigabytes in size, while containers can be measured in a few megabytes.
The following table demonstrates the differences between the two:

Here’s a pictorial view of how the VM and Docker containers differ:

The Docker world can be considered to have these 3 parts:
- Docker Engine
- Client
- Registry
Here is the pictorial representation of the Docker world:

- Docker Engine: This is the server process that manages the runtime environment for containers. A host would have one daemon process running in the background, which provides a remote API for clients to talk to over network sockets.
- Client: Docker provides a command line tool, which is used for working with Docker. Client is used for passing the instructions to the Docker daemon which does the actual work of hosting the container applications. The client/server model allows the client to talk to any number of servers, where the server can be on a remote host.
- Registry: Used for the storage and transfer of container images. There are applications which allow you to run private registries, or you can even make use of cloud/public based ones. The installation process of Docker is well-documented here: https://docs.docker.com/engine/installation/.
Once the installation is done, you can start playing with Docker. As a example, running the following command will set a CentOS instance running locally and place you in its terminal:
docker run -t -i centos:latest