[Docker] Basic

Contents from the book Practical Docker With Python 2018

Containers and Virtual Machines

  • A fundamental difference is that containers share the same kernel as the host

Docker only isolates a single process (or a group of processes,
depending on how the image is built) and all the containers run on the same host system.

In contrast, when a virtual machine is spun up, the hypervisor
virtualizes an entire system—from the CPU to RAM to storage. To support this virtualized system, an entire operating system needs to be installed. For all practical purposes, the virtualized system is an entire computer running in a computer.

Terminology

Layers

A layer is a modification applied to a Docker image as represented by an instruction in a Dockerfile. Typically, a layer is created when a base image is changed—for example, consider a Dockerfile that looks like this:

1
2
3
4
FROM ubuntu
RUN mkdir /tmp/logs
RUN apt-get install vim
RUN apt-get install htop

In this case, Docker will consider Ubuntu image as the base image and add three layers: Creating /tmp/logs and etc.

When Docker builds the image, each layer is stacked on the next and merged into a single layer using the union filesystem. Layers are uniquely identified using sha256 hashes. When Docker scans a base image, it scans for the IDs of all the layers that constitute the image and begins to download the layers.

Docker Image

Docker image is a read-only template that forms the foundation of your application. It is very much similar to, say, a shell script that prepares a system with the desired state.

A Docker image starts with a base image—typically the one selected is that of an operating system are most familiar with, such as Ubuntu.

Docker images are created using a series of commands, known as instructions, in the Dockerfile.

Docker Container

A Docker image, when it’s run in a host computer, spawns a process with its own namespace, known as a Docker container. The main difference between a Docker image and a container is the presence of a thin read/ write layer known as the container layer. Any changes to the filesystem of a container, such as writing new files or modifying existing files, are done to this writable container layer than the lower layers.

An important aspect to grasp is that when a container is running, the changes are applied to the container layer and when the container is stopped/killed, the container layer is not saved.

Stateful applications and those requiring persistent data were initially not recommended as containerized applications. However, with Docker Volumes, there are ways to get around this limitation.

Bind Mounts and Volumes

Docker provides different ways to mount data into a container from the Docker host: volumes, bind mounts, and tmpfs volumes. While tmpfs volumes are stored in the host system’s memory only, bind mounts and volumes are stored in the host filesystem.

Docker Registry

A Docker Registry is a place where you can store Docker images so that they can be used as the basis for an application stack. Some common examples of Docker registries include the following:

  • Docker Hub
  • Google Container Registry
  • Amazon Elastic Container Registry

Dockerfile

A Dockerfile is a set of instructions that tells Docker how to build an image. A typical Dockerfile is made up of the following:

  • A FROM instruction that tells Docker what the base image is
  • A ENV instruction to pass an environment variable
  • A RUN instruction to run some shell commands (install-dependent programs not available in the base image)
  • A CMD or an ENTRYPOINT instruction that tells Docker which executable to run when a container is started

Docker Engine

Docker Engine is the core part of Docker. Docker Engine is a client-server application that provides the platform, the runtime, and the tooling for building and managing Docker images, Docker containers, and more. Docker Engine provides the following:

  • Docker daemon
  • Docker CLI
  • Docker API

Docker Daemon

The Docker daemon is a service that runs in the background of the host computer and handles the heavy lifting of most of the Docker commands. The daemon listens for API requests for creating and managing Docker objects, such as containers, networks, and volumes.

Docker CLI

The Docker CLI forwards the request to Docker daemon, which then performs the necessary work.

  • docker build
  • docker pull
  • docker run
  • docker exec

Docker API

Docker also provides an API for interacting with the Docker Engine. This is particularly useful if there’s a need to create or manage containers from within applications. Almost every operation supported by the Docker CLI can be done via the API.

Docker Compose

Docker Compose is a tool for defining and running multi-container applications. Much like how Docker allows you to build an image for your application and run it in your container, Compose use the same images in combination with a definition file (known as the compose file) to build, launch, and run multi-container applications, including dependent and linked containers.

Docker Machine

Docker Machine is a tool for installing Docker Engines on multiple virtual hosts and then managing the hosts. Docker Machine allows you to create Docker hosts on local as well remote systems, including on cloud platforms like Amazon Web Services, DigitalOcean, and Microsoft Azure.

Getting Start with Docker Commands

  • docker image ls: list of images available locally
  • docker image inspect DOCKERNAME: inspect the docker image
  • docker pull DOCKERNAME: Pull a specific version of Docker image. i.e: docker pull nginx:1.12-alpine-perl
  • docker run -p 80:80 <IMAGE_ID>: Run nginx docker image on localhost 80
    • curl http://localhost:80 Will set a GET request to the webserver where nginx image is running.
    • -p flag tells Docker to publish the exposed port from the Docker container to the host
    • Exposing port allows the local machine to talk with containers
    • The first parameter after the flag is the port on the Docker host that must be published and the second parameter refers to the port within the container. We can confirm that the image publishes the port using the docker inspect command:
    • docker image inspect nginx | jq .[].Config.ExposedPorts
  • docker ps: List all running containers
    • docker ps -a: List all containers
  • docker stop <container-id>: stop running container
  • docker kill <container-id>
  • docker rm <container-id>: remove the contaienr from local filesystem
  • docker image ls: List all images present in the system. The container should be removed first, then the image