Docker

From Rixort Wiki
Jump to navigation Jump to search

Containers

At a high level, containers are a lightweight form of virtual machines which encapsulate an application and its dependencies. However, there are some key differences between containers and virtual machines:

  • Some resources are shared with the host operating system, which reduces the overhead involved in comparison with a VM. How much overhead is debatable, especially given that hardware support for virtualisation exists on most modern CPUs, and any machine operating as a server is likely to have this available and enabled.
  • Portability of containers should make them easier to deploy and migrate across hardware.
  • Lower resource utilisation, particularly RAM and CPU, means running a dozen containers is more realistic than the same number of VMs, especially on a developer's laptop.
  • Due to the sharing of resources, containers always run the same kernel as the host.
  • Containers are usually faster to start and stop than virtual machines. This helpful if you want to spin up a container, run a particular task, and then stop it immediately, e.g. for transaction processing.
  • Containers operate within their own namespaces, including processes. As a result, each container can have a process with PID 1, and these will not conflict with each other.

Requirements

  • Modern kernel
  • 64 bit Linux

Security

  • The Docker daemon currently requires root privileges. As a result, all docker commands must be prefixed with sudo, or alternatively you can create a group called docker and add users to that. This does not provide any security benefits.

Basic running

docker run debian

Starting a container with an interactive shell:

docker run -i -t debian /bin/bash

Creating a container without running it (i.e. created in 'stopped' state):

docker create debian

When creating a container, it may be useful to capture the container ID as an environment variable:

CONTAINER_ID=$(docker create debian)

Each container gets a long UUID (hex-encoded 1024 bit value). In most cases you can refer to the container using a short version of the UUID (usually 12 characters), or you can give it a name. Docker also generates names using a personal adjective followed by an underscore and the last name of a famous person, e.g. serene_mahavira.

Tab-completion is available for images which you have previously run.

docker restart [name] will restart a container.

docker logs shows everything written to the stdout or stderr streams. By default it is never rotated or truncated, so is not a sensible option for long-lived processes.

docker stop halts the process with PID 1 in the container.

docker exec [name] [command] will run the command in the specified container.

docker pull [name]:[tag] will download the tagged version of the container without running it.

Environment variables

Multiple environment variables can be passed into the container using -e:

docker run --detach --rm -e MYSQL_USER=my_user -e MYSQL_DATABASE=my_database -e MYSQL_PASSWORD=my_password -e MYSQL_RANDOM_ROOT_PASSWORD=true mysql:5.7

Running a command within a container

A combination of docker run, --rm and mounting a volume (--volume) can demonstrate a command being run within a container:

docker run --rm --volume $(pwd):/app php:latest php /app/example.php

Logging into an existing container

Attaching an interactive terminal to the named container:

docker exec -it [container] bash

This command assumes Bash is installed, if not then sh may work.

Detached terminals

Passing the --detach option starts the container in the background and unattached to the terminal. This is a sensible option for server software such as Nginx.

Read-only file systems

To start a container with a read-only file system, pass the --read-only flag to docker run:

docker run --read-only debian

Port mapping

Port mapping from the container to the host can be accomplished using -p or --publish:

docker run container:latest -p 80000:80

The above command will map port 80000 on the host to port 80 inside the container.

Container states

Containers will always be in one of four states:

  • Running
  • Paused
  • Exited (stopped)
  • Restarting

By default, docker ps will only show running containers.

Configuration

Build configuration is contained in a file named Dockerfile.

All Docker configurations must start with a FROM instruction, which specifies the base image and optionally a tagged version, e.g. debian:stretch.

Arbitrary commands can be run using RUN [command].

docker build . will build an image in the current directory, using ./Dockerfile.

Docker Compose or an .env can be used to define how a container is started, e.g. environment variables.

Images

docker images will list all images on the host.

Although most images will come from a registry, it is possible to load an image from a file using docker load.

Cleanup

Containers only run as long as their main process. However, exiting the main process will only stop the container, it will not remove it from disk. To do this you must run:

docker rm [container]

Passing --rm to docker run will automatically delete the container when the main process exits, e.g.

docker run --rm debian echo "Hello World"

docker ps -a will show all containers, included those which have been stopped.

All stopped Docker containers can be removed with the following command:

docker rm -v $(docker ps -aq -f status=exited)

All stopped containers, networks not used by at least one container and images not associated with a container can be removed with:

docker system prune

Registries

A registry contains images which can be downloaded using docker pull. Anyone can run a registry (private or public), but by default Docker will use Docker Hub