Docker Cheat Sheet

An extraordinarily verbose compilation of useful Docker commands, where they are used and examples

Temporary Note
Until all content in this early draft Docker Cheat Sheet has been reviewed, unreviewed content is preceded by Note - this section under review

Table of Contents - Main Sections only

see Index for links to all sections

Prerequisites, Docker Installation

If you are running on Windows, Solaris, BSD or some other non Linux OS, run Docker in a virtualization technology like Virtualbox, VMware, Hyper-V. If running on Windows and you are only mildly familiar with virtualization, boot2docker is a project that installs Virtualbox, tinycorelinux(Debian based) and docker with a number of desirable apps like ssh at once. If you are experienced with any virtualization or already have some kind of virtualization installed, you can create a Guest and install Docker in that Guest in an ordinary way.

Whatever distro you prefer, Docker should be installed according to directions for your distro. As of this writing docker can be installed using the regular repositories for Ubuntu, CentOS, Fedora and likely many more. Docker Install instructions can be found on this Docker documentation page. A better guide for installing docker on OpenSUSE is here:

http://en.opensuse.org/User:Tsu2/docker

Images

The Docker reference.
An image is a basic building block. Public images typically have only minimal configurations, ready for you to customize and create a running environment (a container).

Common Image management commands

  • docker images displays all images in the local repository.
  • docker import extracts an image from a tarball file into the local repository.
  • docker build creates image from Dockerfile.
  • docker commit creates image from a container.
  • docker rmi removes an image from the local repository.
  • docker insert inserts a file from URL into image. (kind of odd, you'd think images would be immutable after create)
  • docker load Using STDIN, loads an image with its tags from a tar archive
  • docker save saves an image to a tar archive by streaming to STDOUT with all parent layers, tags & versions.
  • docker history displays the steps used to create and modify the image. Important to understand among things the underlying distro used, TCP/IP ports presented to docker (You then need to match those ports with your "docker run" command)

Containers

A Container is the isolated runtime environment which is created from an image. Within a container there can be an app, OS, or anything you want running. Containers are like highly featured chroots, but with much more advanced features you might find in other virtualization technologies.

A typical container life-cycle might be

  • Launch a generic container from a generic image
  • Access the console and modify the application as it's running from inside the container
  • Commit your container, thereby creating a new image which now contains your configuration modifications. When you stop and next time start your new container, it will retain your changes.

Common Container management commands

If you want to create and run a temporary container, docker run --rm will remove the container after it stops.

Containers generally are created to run either as a background process (aka "service") or as an interactive "foreground" (normal app). Another way to compare the two is that a background "daemon" container continues to run without a logged in User. A foreground "normal app" container instantiates with immediate access to a running console, and when the User exits/quits the console the container also stops.

  • An example creating a daemon/service/background "detached" container specifying an optional custom container name
'docker run -d --name containername imagename'
  • An example creating a foreground/normal app, specifying an interactive tty bash console.
'docker run -it --name containername imagename /bin/bash'

If you want to map a directory(often described as "folder sharing") on the host to a docker container,

 `docker run -v $HOSTDIR:$DOCKERDIR` (also see [Volumes](#volumes) section).

Incoming Network Connections

If you want to allow incoming network connections to the app in your container, see the exposing ports section.

Configuring a Container to auto start on boot

This is described in the Docker documentation as host process manager integration. In plain words, after you have a tested running container, you invoke it with "docker start -a" and modify the docker daemon (ie if using systemd, modify the Unitfile) to start with "-r=false." You can find a sample Unitfile script in the referenced Docker documentation.

Info

  • docker ps lists running containers.
  • docker ps -a lists all containers, both running and stopped.
  • docker inspect queries a container or image for low level information
  • docker logs gets logs from container.
  • docker events gets events from container.
  • docker port identifies the external port number for the specified container port (See EXPOSE)
  • docker top shows running processes in container.
  • docker diff shows changed files in the container's file system.

Import / Export

Note - this section under review and will be modified to describe the ADD dockerfile command)

  • docker cp copies files or folders out of a container's filesystem.
  • docker export turns container filesystem into tarball.

Entering a Docker Container

The most recommended way to gain access to a console of a running docker container is to use nsenter. Using an sshd daemon is the official documentation but considered evil. Note that sshd requires installing and configuring sshd, exposing a network stack and remoting in using TCP/IP sockets. Aside from the complexity setting that all up, it's also not always possible. Nsenter uses unix sockets minimizing dependencies and complexity, so in theory should be less complex and more universally usable.

nsenter allows you to run any command from a console within the running container. If the container doesn't already have the pre-isntalled app or tool, you can often install the app on the fly. If that's not possible, then you may need to build your own image and pre-install the tool or app.

The nsenter documentation you follow should describe how to use a command "docker-enter" which is a wrapper for nsenter with a series of commonly desired command attributes (see the official nsentern documentation for more details). You can also append a command to the end of the docker-enter command if you wish to execute the command by default (not typically necessary).

Info

  • docker history displays how the image has been built.
  • docker tag assigns a custom name/alias to the image (local or registry).

Registry & Repository

Note: This section under review
A repository is a hosted collection of tagged images. The public docker repository can be searched with "docker search" When a copy of the image is downloaded and stored locally for personal use, you have a local repository. You can also specify other private repositories.

A registry is a host -- a server that stores repositories and provides an HTTP API for managing the uploading and downloading of repositories.

Docker.io hosts its own index to a central registry which contains a large number of repositories.

Dockerfile

Dockerfile (exactly as shown including capitalized "D") is the configuration file used to build an image. Can be thought of as the "Install file" that defines the steps used to build an image. Typically it will start with a base image defined by FROM, identify its creator/maintainer with MAINTAINER, a sequence of RUN steps, define some app ports with EXPOSE and end by executing a CMD or ENTRYPOINT to start an application

Some Common Dockerfile Elements

Tutorials

Flux7's Dockerfile Tutorial

Docker Documentation Examples

Note that the official Docker Examples describe techniques and methods, and not simply ways to implement a solution described by the example title. The technique and method is hidden and not described obviously, it's up to the Student to identify and extract those lessons.

Layers

Note: This section under review

The versioned filesystem in Docker is based on layers. They're like git commits or changesets for filesystems.

Links

Note: This section under review

Links are how two Docker containers can be combined (http://docs.docker.io/use/working_with_links_names/). Linking into Redis and Atlassian show examples. You can also resolve links by hostname.

UPDATE NOTE: From here to the end of this "Links" section, the following example is from the original pre-fork cheat sheet and has not been verified

NOTE: If you want containers to ONLY communicate with each other through links, start the docker daemon with -icc=false to disable inter process communication.

If you have a container with the name CONTAINER (specified by docker run --name CONTAINER) and in the Dockerfile, it has an exposed port:

EXPOSE 1337

Then if we create another container called LINKED like so:

docker run -d --link CONTAINER:ALIAS --name LINKED user/wordpress

Then the exposed ports and aliases of CONTAINER will show up in LINKED with the following environment variables:

$ALIAS_PORT_1337_TCP_PORT
$ALIAS_PORT_1337_TCP_ADDR

And you can connect to it that way.

To delete links, use docker rm --link .

Volumes

Note: This secion under review

Docker volumes are free-floating filesystems. They don't have to be connected to a particular container.

Volumes are useful in situations where you can't use links (which are TCP/IP only). For instance, if you need to have two docker instances communicate by leaving stuff on the filesystem.

You can mount them in several docker containers at once, using docker run -volume-from

Because volumes are isolated filesystems, they are often used to store state from computations between transient containers. That is, you can have a stateless and transient container run from a recipe, blow it away, and then have a second instance of the transient container pick up from where the last one left off.

See advanced volumes for more details.

Exposing ports

aka Setting up Incoming Network Connections
The official Docker documentation.

Some fundemental docker architecture should be reviewed here

  • Docker Containers are runtime instances based on Images.
  • Docker security is like a shell around the running container
  • Apps running in a Container must inform Docker from the inside what ports the app wants to accept connections.
  • The "docker run" command completes the TCP/IP networking configuration from the outside by defining at least the following
    -- The networking stack to be used
    -- The real world IP address to be used
    -- The LInux Bridging Device to be used
    -- The re-mapped port to be used to avoid contention

If any networking parameter is not defined explicitly in the "docker run" command, defaults are applied. In some cases this is acceptable, but some configs like specifying incoming ports are best explicitly defined so are consistent and easily known (else would be random).

To tell docker your app wants to use a standard app port (don't worry if this might conflict in the real world, with "docker run" this standard port will be either mapped to the standard port or remapped if necessary)

EXPOSE <CONTAINERPORT>

This command tells docker an app running inside the container wants to accept incoming connections on this standard app port. Note that the way docker works, actual networking configuration is configured in docker itself so no other networking like ip addressing is defined.

In the following example, the container is intended to run in daemon mode (aka background like a service. The alternative is to define and immediately run a console), a localhost address is defined (warning, this won't work in a virtualized environment if docker is running in something like Virtualbox. A known issue is that you must use an actual network address that's not localhost). The real world mapped port is $HOSTPORT separated from the port defined by EXPOSE called $CONTAINERPORT. A custom name is optionally defined followed by the image the container is created from.

docker run -d -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT --name CONTAINER -t someimage

If you forget what you mapped the port to on the host container, use docker port to display it:

docker port CONTAINER $CONTAINERPORT

Tips

Reference an image or container with only a couple taps

Probably the most tedious part of Docker is typing all those odd names and long ID strings. Supercharge your work with the following techniques!

Use Custom names, make them descriptive and short

If you can remember what they mean, a letter or number might be enough

Just type the first couple or few numbers in the ID

The actual containerid or imageid is over 40 characters long (I haven't counted what the actual number is. Listing the container or image (eg docker ps or docker images) displays a truncated string but you can type even fewer digits! As an example, if you have fewer than 10 images in your local repository, typing only the first two digits is already likely unique enough to reference a specific image and that is all that's necessary,

The following example removes an image with an imageid that starts with a1b2c3d4e5f5

docker rmi a1

Note: The rest of this section is under review
A useful comment about the following
Add or replace some of the following commands using the following syntax, an example follows which is used for nsenter
docker inspect --format '{{.State.Pid}}' ..."

Source for the next tips:

Last Ids

alias dl='docker ps -l -q'
docker run ubuntu echo hello world
docker commit `dl` helloworld

Commit with command (needs Dockerfile)

docker commit -run='{"Cmd":["postgres", "-too -many -opts"]}' `dl` postgres

Get IP address

Docker inspect dl | grep IPAddress | cut -d '"' -f 4

docker inspect --format '{{ .NetworkSettings.IPAddress }}' ..."

or

wget http://stedolan.github.io/jq/download/source/jq-1.3.tar.gz
tar xzvf jq-1.3.tar.gz
cd jq-1.3
./configure && make && sudo make install
docker inspect `dl` | jq -r '.[0].NetworkSettings.IPAddress'

or (this is unverified)

docker inspect -f '{{ .NetworkSettings.IPAddress }}' <container_name>

Get port mapping

docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' <containername>

Get Environment Settings

docker run --rm ubuntu env

Delete old containers

docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm

Delete stopped containers

docker rm `docker ps -a -q`

Show image dependencies

docker images -viz | dot -Tpng -o docker.png

Misc Useful tips

Containers are not limited to running a single command or process. You can use supervisord or runit.

If you use jEdit, wsargent has put up a syntax highlighting module for Dockerfile you can use.

A list of useful Dev related commands, useful for building and troubleshooting images and containers, currently very new Docker Dev Corner

My openSUSE Wiki articles

Install Docker on openSUSE
http://en.opensuse.org/User:Tsu2/docker
Access a Container Console
http://en.opensuse.org/User:Tsu2/docker-enter
Build your own Custom Container
http://en.opensuse.org/User:Tsu2/docker-build-tutorial-1

Interesting Docker links

15 Quick Docker Tips
https://github.com/putztzu/docker-cheat-sheet.git
10 Docker Tipst
Includes displaying a graphic imaget
http://nathanleclaire.com/blog/2014/07/12/10-docker-tips-and-tricks-that-will-make-you-sing-a-whale-song-of-joy/``

Credit to Original Work

Based on original work by www.github.com/wsargent.

Index