Docker FAQ

Share on:

Table of Contents

Introduction

This text explains the basics of Docker using a Frequently Asked Questions (FAQ) approach.

Assumptions:

  1. The Docker version is 1.11
  2. The OS is Linux Mint Rosa 17.3 (Ubuntu derivative)
  3. The docker ... commands must be executed as root and it is up to the user to use sudo or log in is as root.

Docker Installation

How do you install Docker?

Step 1: First update the repository and add the necessary key:

1sudo apt-get update
2sudo apt-get install apt-transport-https ca-certificates
3sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

Step 2: Add the Docker repository:

1sudo vim /etc/apt/sources.list.d/docker.list
2i
3deb https://apt.dockerproject.org/repo ubuntu-xenial main

Step 3: Install Docker using apt-get:

1sudo apt-get update
2apt-cache policy docker-engine
3sudo apt-get install docker-engine

Step 4: Startup Docker and verify that it is up and running:

1sudo service docker start
2sudo docker run hello-world

Step 5: Adjust the firewall so that it doesn’t drop packets.

Open /etc/default/ufw, locate DEFAULT_FORWARD_POLICY="DROP" and change to "ACCEPT".

1sudo vim /etc/default/ufw 
2sudo ufw reload

How do you enable Docker at boot time?

1sudo systemctl enable docker

How do you disable Docker at boot time?

1sudo systemctl disable docker 

How do you stop/start/restart the Docker daemon?

Start:

1systemctl enable docker

Stop:

1systemctl stop docker

Restart:

1systemctl restart docker

How do you check whether Docker is running?

Use sudo systemctl status docker or sudo docker info.

How do I configure the daemon’s startup properties?

Edit the file /lib/systemd/system/docker.service and then be sure to issue a sudo systemctl daemon-reload command so that the new configuration is loaded.

How do I bind the Docker daemon to a different interface?

By default, docker binds to a local Unix socket:

1docker daemon -H unix:///var/run/docker.sock

We can change this using the --host or -H flag:

1docker daemon -H tcp://192.168.1.23:5555

Multiple instances of the -H flag will result in the Docker daemon binding to multiple interfaces.

On the client side, the -H can be used to specify the daemon’s interface. Optionally, the DOCKER_HOST environment variable may be used too.

Launching and Managing Containers

What does it mean to “launch” a container?

Launching a container means selecting a Docker image and running a command inside of it.

How do you run a one-off command?

Use the docker run <image> <command> command. For example:

1docker run ubuntu printenv

In the above case, the container will be stopped after the command printenv has produced its results.

How do you interact with a command?

Use the -i (interactive) flag when using the docker run command. For example:

1docker run -i ubuntu passwd
1Enter new UNIX password: perro
2Retype new UNIX password: perro
3passwd: password updated successfully

This -i flag leaves the container’s STDIN stream open.

How do you run full terminal capabilities?

If the command provided to run docker is bash, we normally want full terminal capabilities so that we can run text editors such as vim and have autocompletion capabilities on the command line.

In the described case, we use the -t (allocate pseudo-TTY) flag which may be combined with -i as -it:

1docker run -it ubuntu bash
1root@abe7f8978e4c:/# ps xa
2  PID TTY      STAT   TIME COMMAND
3    1 ?        Ss     0:00 bash
4    9 ?        R+     0:00 ps xa

How do you name a container?

Use the --name <container> flag. For example:

1docker run --name gato_lindo ubuntu ls

How do you run a container as a daemon?

Use the -d flag. For example:

1docker run --name gato_feo -d ubuntu /bin/sh -c "while true ; do echo -n The time is... ; date +%H:%M:%S ; sleep 1 ; done"

Please note that if the intention is to launch a container that stays up, it is not sufficient to specify the -d flag. The container must run a non-daemon, and non-terminating command so that it remains running. If the command goes in the background or it terminates, the container will be stopped.

How do you automatically restart a container if it fails?

The --restart flag restarts the container automatically based on the container’s running process exit code:

Flag Description


--restart=no Never restart: default. --restart=always Ignore the exit code: always restart. --restart=unless-stopped Ignore if it has been stopped before. --restart=on-failure Only if non-zero exit code. --restart=on-failure:3 Same as above but max 3 attempts.

How do you override the image’s startup command?

If the image defines the startup command by using the CMD declaration in the Dockerfile, it is just a matter of specifying the required command as the last argument to docker run.

However, an image may define an automatic command to be executed when a container is run via the ENTRYPOINT declaration. (see Dockerfile Configuration). To override this command, use the --entrypoint="<command>" flag.

For example:

1docker run -ti --entrypoint="bash" apache_image

How do you launch the container inside a default directory?

Use the -w flag. For instance:

1docker run -ti -w /etc/init.d ubuntu ls
1README                  hwclock.sh             mountnfs.sh  sendsigs
2bootmisc.sh             killprocs              ondemand     single
3checkfs.sh              mountall-bootclean.sh  procps       skeleton
4checkroot-bootclean.sh  mountall.sh            rc           umountfs
5checkroot.sh            mountdevsubfs.sh       rc.local     umountnfs.sh
6halt                    mountkernfs.sh         rcS          umountroot
7hostname.sh             mountnfs-bootclean.sh  reboot       urandom

How do you specify a runtime environmental variable?

Use the -e flag. For instance:

1docker run -ti -e "TERM=linux" ubuntu bash
1root@dc6cf98ed6a6:/# echo $TERM
2linux

How do you run a command inside a running container?

Use the docker exec <container> command which accepts similar flags as the docker run command.

For example, let’s suppose gato_feo is a running container.

To run a command and see its results, just specify the container name as opposed to the image name:

1docker exec gato_feo ps -xa

If you are not interested in the results, you can run a command in the background, use the -d flag:

1docker exec -d gato_feo rm /tmp/old.log

As in the case of run, you can also run full terminal capabilities using the -it flag:

1docker exec -i -t gato_feo bash

How do I attach to a daemonised container?

A daemonised container will be normally be sending its STDOUT stream to the Docker logger. However, it is possible to attach directly to it using the docker attach command.

For example:

1docker attach gato_lindo

Please note that docker attach is not the same as docker exec It simply connects the container’s parent (PID = 1) running process STDIN/STDOUT streams to the current terminal.

To detach without stopping the container, press CTRL+p, followed by CTRL+q.

How do you list the containers you have launched?

Use the docker ps command with different flags subject to how you want to filter the results.

Show running containers only: no flag.

1docker ps

Show all containers regardless of whether they are running or not:

1docker ps -a

Show the last container that was launched:

1docker ps -l

Show the last n containers that were last launched:

1docker ps -n 10

How do you remove a container?

You can remove a container by name or by id using the docker rm command. The flag -f (force) will kill the container before removing it.

Examples:

1docker rm gato_lindo
2docker rm 68685c007cf7
3docker rm -f gato_feo

Monitoring and Controlling a Container

How to inspect the processes running inside a container?

You can use the docker top command to get a one-off word:

1docker top gato_feo

But also, you can get real-time statistics using docker stats <container1> <container_n> ...:

1docker stats gato_feo gato_lindo

How do you obtain all settings that apply to a container?

The docker inspect command provides a JSON document with in-depth details about a container regardless of whether it is stopped or running. It may inspect various containers at the same time.

1docker inspect gato_feo
 1[
 2    {
 3        "Id": "22368529243bf94c9846c1ab4478fc2ae011d998c7bc5a30b74dbd492c99c759",
 4        "Created": "2016-07-01T15:51:09.578123484Z",
 5        "Path": "/bin/sh",
 6        "Args": [
 7            "-c",
 8            "while true ; do echo -n The time is... ; date +%H:%M:%S ; sleep 1 ; done"
 9        ],
10        "State": {
11            "Status": "exited",
12            "Running": false,
13            "Paused": false,
14            "Restarting": false,
15            "Dead": false,
16            "Pid": 0,
17            "ExitCode": 137,
18            "Error": "",
19            "StartedAt": "2016-07-01T16:40:48.534348845Z",
20            "FinishedAt": "2016-07-01T16:49:07.678227024Z"
21        },
22        "Name": "/gato_feo",
23        ...
24     }
25]        

How do you retrieve a container’s individual setting?

Individual fields can be selected using the --format flag. For example:

1docker inspect --format='{{.State.Running}}' perro_feo
1false
1docker inspect --format='{{.Config.Image}}' perro_feo
1ubuntu

Multiple fields may also be combined:

1docker inspect --format='{{.Name}} {{.State.Running}}' perro_feo locuras
1/perro_feo false
2/locuras false

The shorter -f flag may be used as well:

1docker inspect -f {{.State.Running}} perro_feo

How do you check a containers’ logs?

Checking a container’s log means checking its STDOUT and STDERR streams. Let’s assume a container named gato_feo.

See all log output:

1docker logs gato_feo

See all log output and than follow changes:

1docker logs -f gato_feo

See only the last 10 lines:

1docker logs --tail 10 gato_feo

See only the last 10 lines and then follow changes:

1docker logs -f --tail 10 gato_feo

Same as above but with a timestamp:

1docker logs -ft --tail 10 gato_feo

How to change the log driver?

As of version 1.11, supported log drivers are:

  • json-file (default, used by the docker logs command)
  • syslog (redirect log ouput to Syslog)
  • journald
  • gelf
  • flu‐entd
  • awslogs
  • splunk
  • etwlogs
  • gcplogs
  • none

Usage:

1docker run --log-driver="syslog" ...

How do you start a stopped or newly created container?

1docker start gato_feo

How do you stop a running container?

The docker stop command sends the SIGTERM signal to the container’s running process:

1docker stop gato_feo

How do you kill a container by brute force?

The docker kill command, unlike docker stop, sends the SIGKILL signal to the container’s running process:

1docker kill gato_feo

Images

How do you list locally available images?

Use the docker images command

How do you download an image from Docker Hub?

Use the docker pull <image>[:tag] command:

1docker pull centos

How do you search for images?

Use the docker search <TERM> command:

1docker search jenkins

Building Images

How do you build your own image?

Follow these steps:

  1. Create a directory to store our image’s configuration. E.g. mkdir myImage
  2. Create a myImage/Dockerfile file that describes the images’ properties
  3. Use the docker build -t="<image_name>" . to build the image

For example:

1mkdir myImage
2cd myImage
3vim Dockerfile

Contents of Dockerfile:

1FROM ubuntu:latest
2RUN apt-get update
3RUN apt-get -y install perl

Then run:

1docker run perl_image perl -e '@scalar = "Hello" ; print @scalar'
2docker run perl -e '$scalar = "Hello World\n" ; print $scalar'

How do you debug an image that fails to build?

Use the image’s name from the last successful step and run bash inside of it to check what went wrong.

For example:

1...
2Step 2: RUN apt-get update
3  --> Running in 6f7d8a6fd7a5
4  --> d7a8d6a7d8a7
5Step 3: RUN apt-get install -y apachee
6...
7E: Unable to locate package apachee
82016/07/01 12:30 The command [/bin/sh -c apt-get install -ya apachee] 
9returned a non-zero code: 100

The healthy image built before the error is d7a8d6a7d8a7:

1docker run -t -i d7a8d6a7d8a7 bash

Once inside the image, you can type the problematic RUN command and check what went wrong.

How do you check what changes have been applied to an image?

Use the docker history command. For example:

1docker history perl_image
1IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
2da269a070c7e        About an hour ago   /bin/sh -c apt-get -y install perl              43.13 MB            
38ccd6d7bda0d        About an hour ago   /bin/sh -c apt-get update                       37.81 MB            
42fa927b5cdd3        5 weeks ago         /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B                 
5<missing>           5 weeks ago         /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/   1.895 kB            
6<missing>           5 weeks ago         /bin/sh -c rm -rf /var/lib/apt/lists/*          0 B                 
7<missing>           5 weeks ago         /bin/sh -c set -xe   && echo '#!/bin/sh' > /u   701 B               
8<missing>           5 weeks ago         /bin/sh -c #(nop) ADD file:025ef672711f22be39   122 MB              

How do you pass arguments at build time?

Use the --build-arg flag. For instance:

1docker build --build-arg=user="webuser" -t myImage .

Dockerfile Configuration

How do you get started?

You have to create a file named Dockerfile under a directory in which you will be building the image.

Inside Dockerfile, at least you normally have to specify the base image using the FROM image:tag declaration. For instance:

1FROM ubuntu:16.04

How do you set up the base image?

Use the RUN command, which accepts two variations in syntax: a command wrapper and an array format:

  1. RUN <command> which is equivalent to /bin/sh -c <command>
  2. RUN [ "exe", " <arg1>", "<arg2>"] where arguments are optional

For example, to add vim to an ubuntu image:

1FROM ubuntu:16.04
2RUN apt-get update
3RUN apt-get install -y vim

How do you define an image’s environment variable?

Use the ENV <variable> <value> declaration.

Environmental variables can then be referred from within the Dockerfile by prefixing the variable with dollar. For example:

1# Dockerfile
2FROM ubuntu
3ENV JAVA_HOME /opt/jdk
4WORKDIR $JAVA_HOME

How do you expose a TCP port in an image?

Use the EXPOSE <port> declaration in the image’s Dockerfile. For example:

1FROM ubuntu:16.04
2RUN apt-get update
3RUN apt-get install -y apache2
4EXPOSE 80

Note: The above example simply exposes port 80. It does not automatically map the port when it is deployed into a container.

How do you define the startup command?

The command supplied as the last argument of docker run may be defined using the CMD declaration. For example:

1# Dockerfile
2FROM ubuntu
3CMD [ "/bin/bash", "--norc" ]

In this case, bash would be executed automatically when launching the container:

1docker run -ti simple
1bash-4.3#

However, the user may still specify a command as the last argument to docker run so that CMD gets ignored.

1docker run -ti simple ls
1bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
2boot  etc  lib   media  opt  root  sbin  sys  usr

How do you define startup arguments?

If you want to execute a command when a container is launched but you want to have flexibility in terms of its arguments, you can use ENTRYPOINT [ "<command>" ] to define the command that should be executed when the container is run, and, optionally, the CMD [ "arg1","arg2",...] declaration to specify the command’s arguments.

For example:

1ENTRYPOINT [ "/bin/bash" ]
2CMD [ "--norc" ]

In the above case, docker run without a command argument will run /bin/bash --norc but the latter may be optionally overridden:

1docker run -ti simple
1bash-4.3# exit
2exit
1docker run -ti simple --version
1GNU bash, version 4.3.42(1)-release (x86_64-pc-linux-gnu)
2Check the **Running an Image** section to see how to
3override these options when running a container	.

The ENTRYPOINT declaration may be overridden using the --entrypoint flag when using the docker run command. In the below example, both the ENTRYPOINT and the CMD declarations are being overridden:

1docker run -ti --entrypoint="/bin/ls" simple -la
1total 72
2drwxr-xr-x  33 root root 4096 Jul  2 16:47 .
3drwxr-xr-x  33 root root 4096 Jul  2 16:47 ..
4-rwxr-xr-x   1 root root    0 Jul  2 16:47 .dockerenv
5drwxr-xr-x   2 root root 4096 May 25 23:11 bin
6drwxr-xr-x   2 root root 4096 Apr 12 20:14 boot
7drwxr-xr-x   5 root root  380 Jul  2 16:47 dev
8drwxr-xr-x  45 root root 4096 Jul  2 16:47 etc
9...

How do you setup a working directory?

Rather than referring all commands using absolute paths, a default working directory may be defined using the WORKDIR declaration.

How do you copy files to the image?

Use the ADD <source> <destination> declaration, which supports various modes:

Copy file: In this case, <source> is a file within the build directory only. For example:

1ADD config.xml /var/lib/app/config.xml

Fetch file from URL: In this case is a file that will be retrieved from an URL. For example:

1ADD http://intranet/config.xml /var/lib/app/config.xml

Unpack archive file: In this case is an archive file such as .tar, .tar.gz, etc. For example:

1ADD images.tar /var/www/images/

Alternatively, the COPY declaration may be used which will avoid any unpacking when dealing with archive files.

How do you add metadata?

Use the LABEL <variable>="<value>" declaration. For example:

1LABEL release="1.2"

Multiple label may also appear in the same line. For example:

1LABEL release="1.2" author="ernie" 

The labels can be extracted using the docker inspect command:

1docker docker inspect -f {{.ContainerConfig.Labels}} gato_lindo
1map[author:ernie release:1.2]
1docker inspect -f {{.ContainerConfig.Labels.author}} gato_lindo 
1ernie

How do you specify default build arguments?

Defaults for the --build-arg flag passed to the docker build command may be specified using the ARG <value> or ARG <name>=<value> declarations. For example:

1ARG betaImage
2ARG runAs=webuser

Volumes

What are volumes?

Volumes are Docker’s mechanism to writing and sharing persistent data (that survives stopping a container). All volumes have in common the fact that they appear as mount points inside the container. However, how (and to what object) the mount point is connected to the outside world may vary:

  1. A host’s directory: A regular UNIX path sitting within the host.

  2. A new volume: A new volume is created when the container is launched but it is not deleted when it is stopped unless special directives are provided.

  3. A volume registered by a container: When a new volume is created, in reality it is associated with the container’s name. Therefore, a second container may refer the volume created by a previous one. This way we stop creating brand new volumes every time which is not very useful anyway.

How do you mount a host’s directory?

Use the -v <host_path>:<mount_point> flag. For instance:

1docker run -ti -v /tmp:/outsidetmp ubuntu bash
1root@8883750fbf8b:/# ls -la | grep out
2drwxrwxrwt  15 root root 4096 Jul  2 18:24 outsidetmp

Note: Hosts’ directories cannot be mounted using a Dockerfile declaration.

How do you create a new volume?

A new volume is creating using the -v <mount_point> flag when running the docker run command or by using the VOLUME <mount_point> declaration inside a Dockerfile.

For example:

1docker run -ti -v /myvolume ubuntu bash
1root@e9c53b0b5906:/# cd myvolume
2root@e9c53b0b5906:/myvolume# echo "Hello My Volume" >> hello.txt
3root@e9c53b0b5906:/myvolume# exit

Even though we have stopped the container by exiting it, we can still find the file:

1find /var/lib/docker -name "hello.txt"
1/var/lib/docker/volumes/a5620c14aae707/_data/hello.txt

Alternatively, you can also find out about the volume’s properties using the docker inspect command. For example:

1docker inspect -f {{.Config.Volumes}} pipo

Please note that the volume id has been shortened for formatting

Networking

How do you find out which port a container is mapped to?

Use the docker port <container> command. For example:

1docker port apache_container
180/tcp -> 0.0.0.0:32769

You may also specify a specific port number if there are many that are exposed:

1# docker port apache_container 80
20.0.0.0:32769

How do you find out a container’s internal IP address?

1docker inspect -f {{.NetworkSettings.Networks.bridge.IPAddress}} server
1172.17.0.1

How do you connect two containers?

Containers that listen on a TCP port are, by default, available on the Docker’s bridge virtual network. For example, let’s suppose that we have a server that listens on port 8000 that is exposed and mapped to port 80 and a client that takes the server’s URL:

1export SERVER_IP=`docker inspect -f {{.NetworkSettings.Networks.bridge.IPAddress}} server`
2docker run --name client client_image $SERVER_IP:8000

As you can see, the exposed port (80) is irrelevant in the case of the client reaching the client via the Docker’s bridge.

However, what if we want the client container to talk to the regular host’s network interface? In this case we have to use the --net="host" flag when we invoke the client and use the mapped port instead. For example:

1docker run --name client --net="host" client_image http://localhost:80 

Before You Leave

🤘 Subscribe to my 100% spam-free newsletter!

website counters