Docker is a platform that allows you to build, ship and run applications in a controlled environment called a container. Containers provide isolation from each other and from the underlying infrastructure.
Docker has support for Linux and Windows-based containers. Containers consume less resources than traditional VMs, and processes running in containers actually share the base operating system kernel. Although containers are self-sufficient and contain everything the application needs to run, they aren't portable across platforms or architectures. For instance, Linux x86 containers will not run on Windows machines or Linux ARM machines.
Docker Images and Containers
The primary unit of work under Docker is a running Docker container.
A Docker container is launched from a Docker image, much like a running process is launched from a program on disk. The Docker image provides the filesystem view for the container, along with metadata about the runtime, like environment variables, volumes, ports exposed, etc.
Docker images are built and shipped as an ordered collection of filesystem layers and are progressively built layer by layer. Docker images can be built via the Docker CLI and a recipe called a Dockerfile, or by one of the many third-party tools that do the same job. The Docker native build command interprets the Dockerfile line by line. Each interpreted line results in a new filesystem layer or a piece of metadata about the final image.
Here's an example of a Dockerfile:
MAINTAINER Andras Mitzki <firstname.lastname@example.org>
RUN apt-get update -qq && apt-get install -y \
RUN wget -qO - https://download.opensuse.org/repositories/home:/laszlo_budai:/syslog-ng/Debian_8.0/Release.key | apt-key add -
RUN echo 'deb http://download.opensuse.org/repositories/home:/laszlo_budai:/syslog-ng/Debian_8.0 ./' | tee --append /etc/apt/sources.list.d/syslog-ng-obs.list
RUN apt-get update -qq && apt-get install -y \
ADD openjdk-libjvm.conf /etc/ld.so.conf.d/openjdk-libjvm.conf
ENTRYPOINT ["/usr/sbin/syslog-ng", "-F"]
See https://docs.Docker.com/engine/reference/builder for more information on Dockerfiles.
A Docker registry is a server or service that acts as a repository for Docker images. The registry stores images as a collection of layers. Layers are identified by their checksum. This allows Docker and the registry to de-duplicate layers. When Docker pushes images to a registry, it only pushes layers that don't already exist on the registry. Similarly, when Docker pulls images from a registry, it only pulls layers that it doesn't already have.
Docker registries can run on-premises or in the cloud. There are commercial as well as free offerings for both. Some registries require authentication and provide access control for operations on the registry.
See the Docker usage summary section on how to authenticate with a Docker registry.
Running a Container
When Docker launches a container, it first pulls all the filesystem layers that comprise the image to the local filesystem. This image is then mapped as the root of the container filesystem. Docker also allows for the creation of independent volumes that can be attached to multiple containers. You can map volumes from the host machine into the container, ports from the public interface to the container, set environment variables, etc. See the command summary section for an example.
Docker Usage Summary
Most examples here are only illustrative. For complete command syntax and options, refer to the links below each. Commands referring to image:tag, can also optionally be prefixed with server:port/ to point to specific Docker registries rather than the default hub.Docker.com.
Logging into a registry:
Usage: docker login [SERVER]
Full documentation: https://docs.docker.com/engine/reference/commandline/login/
Pull an image from the registry:
$ docker pull alpine:3.5
Full docuemtation: https://docs.docker.com/engine/reference/commandline/pull/
List images on the local machine:
$ docker images
Full documentation: https://docs.docker.com/engine/reference/commandline/images/
Remove a local image:
$ docker rmi alpine:3.5
Full documentation: https://docs.docker.com/engine/reference/commandline/rmi/
Launching a container (example):
$ docker run -it --rm -v /host/path:/some/path/in/container -e TERM=xterm -p 443:8443 --name myalpine alpine:3.5 sleep 600
This command funs the Alpine Linux image tagged as 3.5 in interactive (-i) mode with an allocated pseudoterminal (-t). It maps volume (-v) path /host/path on the base OS to /some/path/in/container inside the container. It passes in an environment (-e) variable TERM=xterm into the container. It maps (-p) external port 443 to port 8443 in the running container. Finally, it runs "sleep 600" inside the container. The running container is named (--name) "myalpine".
For more information: https://docs.docker.com/engine/reference/run/
List running containers:
$ docker ps
Add option -a to list all containers including stopped ones
Full documentation: https://docs.docker.com/engine/reference/commandline/ps/
Entering or running a command in a running container:
$ docker exec myalpine ps -ef
Runs ps -ef inside a running container named myalpine
Full documentation: https://docs.docker.com/engine/reference/commandline/exec/
Stopping a container:
$ docker stop myalpine
Stops the container named myalpine
Full documentation: https://docs.docker.com/engine/reference/commandline/stop/
Removing a container:
$ docker rm myalpine
Removes the stopped container named myalpine
Full documentation: https://docs.docker.com/engine/reference/commandline/rm/
Customize Wercker Boxes and Services
Wercker uses Docker containers in the pipeline to provide toolchain boxes and auxiliary services. It might be necessary to customize existing Docker images or create entirely new ones for Wercker boxes or services. The easiest way to do that is with a Dockerfile.
Here's an example that expands the Python container to add Python minifier support. In an empty directory, create a file named Dockerfile that contains this.
RUN pip install pyminifier
This Dockerfile creates a new image from the Python base image. The RUN line adds a new layer that contains the pyminifier package.
To build, tag and push this into the default Docker registry (hub.Docker.com), in the same directory as the Dockerfile, run:
$ docker build -t hubuser/pyminifier:some-tag .
$ docker push hubuser/pyminifier:some-tag
In the above example, hubuser is your Docker Hub username. You may need to authenticate before you can push to the registry.
You can now use this container image in your pipeline definition as: