Docker - Main Components



Table of Contents

Components and Concepts

Docker Engine

Docker engine is the layer on which Docker runs. It’s a lightweight runtime and tooling that manages containers, images, builds, and more. It runs natively on Linux systems and is made up of:

  1. A Docker Daemon that runs in the host computer. The Docker daemon is what actually executes commands sent to the Docker Client, like building, running, and distributing your containers. The Docker Daemon runs on the host machine, but as a user, you never communicate directly with the Daemon.
  2. A REST API for interacting with the Docker Daemon remotely
  3. A Docker Client that then communicates with the Docker Daemon to execute commands. The Docker Client is what you, as the end-user of Docker, communicate with. Think of it as the UI for Docker.
Source: Docker Documentation

Docker CLI

CommandDescription
docker attachAttach local standard input, output, and error streams to a running container
docker buildBuild an image from a Dockerfile
docker builderManage builds
docker checkpointManage checkpoints
docker commitCreate a new image from a container's changes
docker configManage Docker configs
docker containerManage containers
docker contextManage contexts
docker cpCopy files/folders between a container and the local filesystem
docker createCreate a new container
docker diffInspect changes to files or directories on a container's filesystem
docker eventsGet real time events from the server
docker execRun a command in a running container
docker exportExport a container's filesystem as a tar archive
docker historyShow the history of an image
docker imageManage images
docker imagesList images
docker importImport the contents from a tarball to create a filesystem image
docker infoDisplay system-wide information
docker inspectReturn low-level information on Docker objects
docker killKill one or more running containers
docker loadLoad an image from a tar archive or STDIN
docker loginLog in to a Docker registry
docker logoutLog out from a Docker registry
docker logsFetch the logs of a container
docker manifestManage Docker image manifests and manifest lists
docker networkManage networks
docker nodeManage Swarm nodes
docker pausePause all processes within one or more containers
docker pluginManage plugins
docker portList port mappings or a specific mapping for the container
docker psList containers
docker pullPull an image or a repository from a registry
docker pushPush an image or a repository to a registry
docker renameRename a container
docker restartRestart one or more containers
docker rmRemove one or more containers
docker rmiRemove one or more images
docker runRun a command in a new container
docker saveSave one or more images to a tar archive (streamed to STDOUT by default)
docker searchSearch the Docker Hub for images
docker secretManage Docker secrets
docker serviceManage services
docker stackManage Docker stacks
docker startStart one or more stopped containers
docker statsDisplay a live stream of container(s) resource usage statistics
docker stopStop one or more running containers
docker swarmManage Swarm
docker systemManage Docker
docker tagCreate a tag TARGET_IMAGE that refers to SOURCE_IMAGE
docker topDisplay the running processes of a container
docker trustManage trust on Docker images
docker unpauseUnpause all processes within one or more containers
docker updateUpdate configuration of one or more containers
docker versionShow the Docker version information
docker volumeManage volumes
docker waitBlock until one or more containers stop, then print their exit codes

Dockerfile

A Dockerfile is where you write the instructions to build a Docker image. It contains all the commands you would normally execute manually in order to build a Docker image.

Docker can build images automatically by reading the instructions from a Dockerfile. These instructions can be for example:

RUN apt-get y install some-package: to install a software package
EXPOSE 8000: to expose a port
ENV ANT_HOME /usr/local/apache-ant to pass an environment variable
…

Once you’ve got your Dockerfile set up, you can use the docker build command to build an image from it. Here’s an example of a Dockerfile:

FROM openjdk:8-jdk-alpine
ARG JAR_FILE=myapp-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-Djava…","-jar","/app.jar"]
Source: Docker Documentation

Docker Image

A Docker image is a collection of all of the files that make up a software application. Each change that is made to the original image is stored in a separate layer. To be precise, any Docker image has to originate from a base image according to the various requirements.

Each time you commit to a Docker image you are creating a new layer on the Docker image, but the original image and each pre-existing layer remains unchanged.

A base image has been illustrated here. Ubuntu is the base image, and a variety of desired capabilities in the form of functional modules can be incorporated on the base image for arriving at multiple images.

An important distinction to be aware of when it comes to images is the difference between base and child images.

  • Base images are images that have no parent image, usually images with an OS like ubuntu, busybox or debian.
  • Child images are images that build on base images and add additional functionality.

Then there are official and user images, which can be both base and child images.

  • Official images are images that are officially maintained and supported by the folks at Docker. These are typically one word long. In the list of images above, the python, ubuntu, busybox and hello-world images are official images.
  • User images are images created and shared by users like you and me. They build on base images and add additional functionality. Typically, these are formatted as user/image-name.

Images and Containers

A container is launched by running an image (containers are built off images). An image is an executable package that includes everything needed to run an application:

  • the code
  • a runtime
  • Libraries
  • environment variables
  • configuration files

Since images are read-only, Docker adds a read-write file system over the read-only file system of the image to create a container.

Docker Container Lifecycle

Create container

Create a container to run it later on with required image.

docker create --name <container-name> <image-name>

Run container

Run the container with the required image and specified command / process. ‘-d’ flag is used for running the container in background.

docker run -it -d --name <container-name> <image-name> bash

Pause container

Used to pause the processes running inside the container.

docker pause <container-id/name>

Unpause container

Used to unpause the processes inside the container.

docker unpause <container-id/name>

Start container

Start the container, if present in stopped state.

docker start <container-id/name>

Stop container

To stop the container and processes running inside the container:

docker stop <container-id/name>

To stop all the running docker containers

docker stop $(docker ps -a -q)

Restart container

It is used to restart the container as well as processes running inside the container.

docker restart <container-id/name>

Kill container

We can kill the running container.

docker kill <container-id/name>

Destroy container

Its preferred to destroy container, only if present in stopped state instead of forcefully destroying the running container.

docker rm <container-id/name>

To remove all the stopped docker containers

docker rm $(docker ps -q -f status=exited)
Source: github.io

Exercise

Develop - App

where the index.js file is:

const http = require('http');

const hostname = '0.0.0.0';
const port = 8080;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello From NodeJS Container\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

Ship - Image

The Dockerfile looks as follows (it uses alpine as the base image):

FROM alpine
RUN apk update && apk add nodejs
COPY .  /app
WORKDIR /app
EXPOSE 8080
CMD ["node","index.js"]

build the hellojs-image:

$ docker build -t hellojs-image .

Deploy - Container

run the hellojs-cotainer using node.js base images:

$ docker run -d --rm -p 8080:8080 --name hellojs-container  hellojs-image

You can test your application by calling http://127.0.0.1:8080/

  • -d, --detach : Run container in background and print container ID
  • --rm : Automatically remove the container when it exits
  • -p, --publish list : Publish a container's port(s) to the host
  • --name string : Assign a name to the container