Docker FAQ
Table of Contents
Introduction
This text explains the basics of Docker using a Frequently Asked Questions (FAQ) approach.
Assumptions:
- The Docker version is 1.11
- The OS is Linux Mint Rosa 17.3 (Ubuntu derivative)
- The
docker ...
commands must be executed as root and it is up to the user to usesudo
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:
- Create a directory to store our image’s configuration. E.g.
mkdir myImage
- Create a
myImage/Dockerfile
file that describes the images’ properties - 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:
RUN <command>
which is equivalent to/bin/sh -c <command>
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
1ADD http://intranet/config.xml /var/lib/app/config.xml
Unpack archive file: In this case .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:
-
A host’s directory: A regular UNIX path sitting within the host.
-
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.
-
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