Docker Notes for Beginners

Concepts

What is Docker?

Docker is similar to a lightweight virtual machine. Unlike a VM, which simulates a complete operating system, Docker focuses on providing the minimal environment required to run an application. The difference looks like this:

Virtual machine:

A hypervisor runs on the host OS, emulates hardware, and boots a full guest OS with all its dependencies. If you only need to run a single program in isolation this approach is expensive.

Docker:

A Docker container removes the guest OS layer and keeps only the runtime essentials. It uses less disk space than a VM and starts much faster.

Even without a guest OS, Docker can still deliver isolated environments. It does so by sharing the host Linux kernel (Docker on Windows or macOS actually spins up a Linux VM behind the scenes) and by relying on several kernel-level isolation mechanisms. The details are beyond the scope of this post, but plenty of deep dives are available if you want to learn more.

Docker terms

Container

An isolated runtime environment.

Image

The file system snapshot a container runs from. It contains binaries, libraries, configuration, and everything the application needs.

Registry

A service that stores images. Docker uses the official registry by default.

Using Docker

Install

Follow the official installation guide for your platform.

Run a container

On the command line, type:

docker

The CLI prints a summary of available commands. To run a container, use docker run. The example below runs ps -ef inside an Ubuntu container:

1
2
3
4
5
6
7
8
9
10
11
12
13
>>>docker run ubuntu ps -ef
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
latest: Pulling from library/ubuntu
660c48dd555d: Pull complete
4c7380416e78: Pull complete
421e436b5f80: Pull complete
e4ce6c3651b3: Pull complete
be588e74bd34: Pull complete
Digest: sha256:7c67a2206d3c04703e5c23518707bdd4916c057562dd51c74b99b2ba26af0f79
Status: Downloaded newer image for ubuntu:latest
UID PID PPID C STIME TTY TIME CMD
root 1 0 6 10:15 ? 00:00:00 ps -ef

The first argument is the image name—ubuntu in this example. Because the image was not available locally, Docker pulled the latest version from the official registry and then executed ps -ef inside the container.

List images on your machine with docker images.

To download an image without running anything:

docker pull ubuntu

If you want an interactive shell inside the container, add -it:

docker run -it ubuntu bash

Build a custom image

The official images disappear after the container exits; any changes you made inside the container are lost. You can snapshot a modified container with docker commit, but that often leaves junk lying around. The usual approach is to describe the image in a Dockerfile, which records every modification on top of a base image.

Let us borrow the example from the references and build a Debian image with Redis installed. Create a directory named debianredis and add a Dockerfile to it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
FROM debian:jessie

RUN buildDeps='gcc libc6-dev make' \

&& apt-get update \

&& apt-get install -y $buildDeps \

&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \

&& mkdir -p /usr/src/redis \

&& tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \

&& make -C /usr/src/redis \

&& make -C /usr/src/redis install \

&& rm -rf /var/lib/apt/lists/* \

&& rm redis.tar.gz \

&& rm -r /usr/src/redis \

&& apt-get purge -y --auto-remove $buildDeps

FROM selects the base image, and each RUN statement executes commands in the build environment. Chaining commands with && reduces the number of layers, and the cleanup commands drop temporary files so the resulting image stays slim.

Build the image with:

docker build -t debianredis .

Docker reads the Dockerfile in the current directory and produces an image tagged debianredis.

To export the image to a tar archive:

docker save debianredis | gzip > debianredis-latest.tar.gz

Transfer the archive to another machine and load it there:

docker load -i debianredis

You should now see the image on the new host.

References:

  1. Docker — From Beginner to Master
  2. A different look at how Docker works