This document introduces Docker. It discusses that Docker is an abstraction layer for Linux containers that provides lightweight virtualization. Key Docker concepts are explained such as images, containers, volumes, and Dockerfiles which are used to build images. Examples of using Dockerfiles, running containers, and sharing files between the host and containers are provided. Tips are given such as using containers for build processes and monitoring.
4. What’s Docker?
• Abstraction layer for Linux containers
• Written in Google Go (golang)
• Started as an internal project in dotCloud, a
PaaS company
• Open sourced in Mar 2013
• dotCloud pivots and becomes Docker, Inc
• Docker Machine, Swarm and Compose
announced in Dec 2014
5. Why Docker?
• Lightweight resource usage
• Extremely fast startup compared to VMs
• Repeatable, consistent builds (if careful)
• Dependency isolation
• Pristine host OS; only Docker needs to be
installed (easier updates)
6. Why Docker?
• If you want to…
• Upgrade PHP for an app but you have an old
vBulletin installation that needs PHP 5.3
• Run Python 2.7 and Python 3 apps
• Switch your OS entirely
• Get the same image to run on your laptop, your CI
service, staging and production without having to
“bake” different image formats
• Docker makes it relatively painless
7. Vagrant vs. Docker
• Vagrant is an abstraction layer for VMs
• Each VM is a system in its own right (allocated
resources, virtualised hardware)
• Docker containers, however, all make use of
the same underlying host kernel
• Processes in Docker run as regular processes
on the host machine
• This also means Docker is Linux-only; running
Docker on OSX and Windows requires a VM
9. Docker on OSX and Windows
• Use the official boot2docker application
• Convenience wrapper around VirtualBox
• Runs a Tiny Core Linux VM with Docker
• Docker client on host platform
communicates with the Docker daemon in
the VM via TCP
12. Images
• Images are indexed filesystem layers which
combine into a snapshot
• Every additional layer creates a new image
• Many images can share the same base
• Docker provides image management and
distribution
• Docker Hub is a central repository for
uploading and downloading shared images
14. Containers
• Runtime instances of images
• Spawn multiple containers from an image with
individual parameters
• When a container starts, it allocates and isolates
resources (filesystem, network, etc) and executes its
process as PID 1 in this environment
• Containers will retain filesystem changes in a new
read-write layer
• Changes to a container can be persisted to a new
image using docker commit
15. Volumes
• Mount external directories from the host
machine
• Can be a bind mount or a volume attached to
a container; the latter allows you to reference
volumes from other containers
• Typically used to share and persist runtime
data across containers
• Volumes are local to the host machine; they
cannot be distributed like images
16. The Docker Binary
• Daemon and client rolled into one
• The client makes RPC calls to the daemon
• The daemon creates containers as child
processes
• Rocket, an alternative container spec from
CoreOS, delegates this role to systemd
17. docker push
docker pull
registry
FROM debian:wheezy
MAINTAINER blah <me@blah.co>
RUN apt-get install rabbitmq-server
EXPOSE 5672 15672
ENTRYPOINT ["/bin/bash", "-c"]
CMD ["/usr/sbin/rabbitmq-server"]
Dockerfile
docker build
docker tag
image
docker run
container
docker commit
19. Dockerfile format
• Plain text file
• Consists of a series of commands
• Each command creates a new image layer
• FROM - specify the base image tag to build upon
• MAINTAINER - tag the image with name and email
• ENV - set environment flags for subsequent commands
• ADD - copy files, directories, archives, remote urls, etc into the image
• COPY - same as above but without archive or remote url handling
• RUN - execute a command and persist the results as another layer
• EXPOSE - declare TCP or UDP port forwarding
• ENTRYPOINT - specify the process to run as PID 1 (default is /bin/sh -c)
• CMD - argument(s) to pass to entrypoint
20. Sample Dockerfile
FROM debian:wheezy
MAINTAINER Pie <foobar@pie.co>
ENV LC_ALL C
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y curl wget php-fpm
RUN apt-get clean
RUN rm -rf /tmp/* /var/tmp/*
RUN rm -rf /var/lib/apt/lists/*
ENV DEBIAN_FRONTEND newt
21. Sample Dockerfile
FROM debian:wheezy
MAINTAINER Pie <foobar@pie.co>
ENV LC_ALL C
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
&& apt-get install -y curl wget php-fpm
&& apt-get clean
&& rm -rf /tmp/* /var/tmp/*
&& rm -rf /var/lib/apt/lists/*
ENV DEBIAN_FRONTEND newt
22. Sample Dockerfile
FROM debian:wheezy
MAINTAINER Pie <foobar@pie.co>
ENV LC_ALL C
ENV DEBIAN_FRONTEND noninteractive
ADD . /build
RUN /build/scripts/environment.sh
&& /build/scripts/services.sh
&& /build/scripts/cleanup.sh
ENV DEBIAN_FRONTEND newt
23. • Create the image from a Dockerfile in the cwd:
docker build -t pie/base .
• A container spawned from this image will
terminate immediately since there is no command
to run (implicit /bin/sh -c)
• We can pass in a command:
docker run pie/base echo 'hi'
• This container terminates with output
• Stopped containers remain listed in docker ps -a
• To clean up after running:
docker run --rm pie/base echo 'hi'
24. • Inspect the image:
docker inspect pie/base
• You can also view the history (all image layers and their
respective sizes)
docker history pie/base
• Run a container as a background process:
docker run -d --name hi pie/base /bin/sh
-c “while true;do echo 'hi';sleep 1;done”
• View the logs of a running container:
docker logs hi
• “Log into” a running container:
docker exec -it hi /bin/sh
25. Defining the process
FROM pieco/base:latest
MAINTAINER Pie <foobar@pie.co>
RUN apt-get install rabbitmq-server
&& rabbitmq-plugins enable
rabbitmq_management
EXPOSE 5672 15672
ENTRYPOINT ["/bin/bash", "-c"]
CMD ["/usr/sbin/rabbitmq-server"]
26. • Since the process daemonizes, the container
will remain running.
docker run -d --name rabbitmq
pie/rabbitmq
• Find out which ports are exposed:
docker port rabbitmq
15672/tcp -> 0.0.0.0:15672
5672/tcp -> 0.0.0.0:5672
• Now you can interact over TCP:
curl -u guest:guest
"http://192.168.59.103:15672/api/..."
{"status":"ok"}
27. • You can map to different ports:
docker run -d --name rabbitmq
-p 8080:15672 -p 8081:5672
pie/rabbitmq
• Now:
docker port rabbitmq
15672/tcp -> 0.0.0.0:8080
5672/tcp -> 0.0.0.0:8081
• You can also use -P to map all exposed
ports to random ports (49153 to 65535)
29. Scripts vs daemons
• Distinguish between short-lived and long-running
containers
• You can use containers like simple binaries
• e.g. docker run --rm -v $(pwd):/opt pie/git clone
git@github.com:pie/foobar.git /opt/foobar
• This clones a repository into your current directory
using a container with git installed
• Chain several specialised containers to form your
build system (e.g. Composer, gulp, etc)
• Load the compiled app into your runtime container
30. Getting files in and out
• Host <=> container: Use a bind mount
docker run -it -v $(pwd):/opt <image> /bin/sh
• Or pipe your files in:
tar cz - . | docker run -i <image> tar xz -C /opt
• Cross-container: Named volumes
docker run -v /opt --name data <image> /bin/true
docker run -it --volumes-from data <image> /bin/sh
• Container => host: Use docker cp
docker cp <container>:/opt/* .
• Image => host: Use a bind mount
docker run --rm -v $(pwd):/tmp <image> /bin/sh -c
'cp -rf /opt /tmp'
31. Logging and monitoring
• Similar to how you dockerize your apps, you
can also dockerize your logging and
monitoring processes
• Docker provides APIs to collect container
events, output and resource stats
• Use metrics and logging containers that take
advantage of this feature
• Some examples: gliderlabs/logspout,
datadog/docker-dd-agent
32. Beware the cargo cult
• You don’t have to dockerize everything
• You don’t necessarily need an init system;
use for legacy apps (e.g. needs cron)
• Don’t install dependencies and utilities you
don’t need (e.g. sshd)
• Explore using lean base images, you don’t
need Ubuntu to run a PHP/Node/Golang app