Docker FAQ
This is a Docker tutorial written in a Frequently Asked Questions (FAQ) style.
- Introduction
- Docker Installation
- How do you install Docker?
- How do you enable Docker at boot time?
- How do you disable Docker at boot time?
- How do you stop/start/restart the Docker daemon?
- How do you check whether Docker is running?
- How do I configure the daemon’s startup properties?
- How do I bind the Docker daemon to a different interface?
- Launching and Managing Containers
- What does it mean to “launch” a container?
- How do you run a one-off command?
- How do you interact with a command?
- How do you run full terminal capabilities?
- How do you name a container?
- How do you run a container as a daemon?
- How do you automatically restart a container if it fails?
- How do you override the image’s startup command?
- How do you launch the container inside a default directory?
- How do you specify a runtime environmental variable?
- How do you run a command inside a running container?
- How do I attach to a daemonised container?
- How do you list the containers you have launched?
- How do you remove a container?
- Monitoring and Controlling a Container
- How to inspect the processes running inside a container?
- How do you obtain all settings that apply to a container?
- How do you retrieve a container’s individual setting?
- How do you check a containers’ logs?
- How to change the log driver?
- How do you start a stopped or newly created container?
- How do you stop a running container?
- How do you kill a container by brute force?
- Images
- Building Images
- Dockerfile Configuration
- How do you get started?
- How do you set up the base image?
- How do you define an image’s environment variable?
- How do you expose a TCP port in an image?
- How do you define the startup command?
- How do you define startup arguments?
- How do you setup a working directory?
- How do you copy files to the image?
- How do you add metadata?
- How do you specify default build arguments?
- Volumes
- Networking
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:
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
Step 2: Add the Docker repository:
sudo vim /etc/apt/sources.list.d/docker.list
i
deb https://apt.dockerproject.org/repo ubuntu-xenial main
Step 3: Install Docker using apt-get:
Step 4: Startup Docker and verify that it is up and running:
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"
.
How do you enable Docker at boot time?
How do you disable Docker at boot time?
How do you stop/start/restart the Docker daemon?
Start:
Stop:
Restart:
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:
We can change this using the --host
or -H
flag:
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:
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:
Enter new UNIX password: perro
Retype new UNIX password: perro
passwd: 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
:
root@abe7f8978e4c:/# ps xa
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 bash
9 ? R+ 0:00 ps xa
How do you name a container?
Use the --name <container>
flag. For example:
How do you run a container as a daemon?
Use the -d
flag. For example:
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:
How do you launch the container inside a default directory?
Use the -w
flag. For instance:
README hwclock.sh mountnfs.sh sendsigs
bootmisc.sh killprocs ondemand single
checkfs.sh mountall-bootclean.sh procps skeleton
checkroot-bootclean.sh mountall.sh rc umountfs
checkroot.sh mountdevsubfs.sh rc.local umountnfs.sh
halt mountkernfs.sh rcS umountroot
hostname.sh mountnfs-bootclean.sh reboot urandom
How do you specify a runtime environmental variable?
Use the -e
flag. For instance:
root@dc6cf98ed6a6:/# echo $TERM
linux
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:
If you are not interested in the results, you can run a command in the background, use the -d
flag:
As in the case of run
, you can also run full terminal capabilities using the -it
flag:
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:
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.
Show all containers regardless of whether they are running or not:
Show the last container that was launched:
Show the last n containers that were last launched:
docker 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:
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:
But also, you can get real-time statistics using docker stats <container1> <container_n> ...
:
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.
[
{
"Id": "22368529243bf94c9846c1ab4478fc2ae011d998c7bc5a30b74dbd492c99c759",
"Created": "2016-07-01T15:51:09.578123484Z",
"Path": "/bin/sh",
"Args": [
"-c",
"while true ; do echo -n The time is... ; date +%H:%M:%S ; sleep 1 ; done"
],
"State": {
"Status": "exited",
"Running": false,
"Paused": false,
"Restarting": false,
"Dead": false,
"Pid": 0,
"ExitCode": 137,
"Error": "",
"StartedAt": "2016-07-01T16:40:48.534348845Z",
"FinishedAt": "2016-07-01T16:49:07.678227024Z"
},
"Name": "/gato_feo",
...
}
]
How do you retrieve a container’s individual setting?
Individual fields can be selected using the --format
flag. For example:
false
ubuntu
Multiple fields may also be combined:
/perro_feo false
/locuras false
The shorter -f
flag may be used as well:
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:
See all log output and than follow changes:
See only the last 10 lines:
See only the last 10 lines and then follow changes:
Same as above but with a timestamp:
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:
How do you start a stopped or newly created container?
How do you stop a running container?
The docker stop
command sends the SIGTERM
signal to the container’s running process:
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:
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:
How do you search for images?
Use the docker search <TERM>
command:
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:
Contents of Dockerfile
:
Then run:
docker run perl_image perl -e '@scalar = "Hello" ; print @scalar'
docker 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:
...
Step 2: RUN apt-get update
--> Running in 6f7d8a6fd7a5
--> d7a8d6a7d8a7
Step 3: RUN apt-get install -y apachee
...
E: Unable to locate package apachee
2016/07/01 12:30 The command [/bin/sh -c apt-get install -ya apachee]
returned a non-zero code: 100
The healthy image built before the error is d7a8d6a7d8a7
:
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:
IMAGE CREATED CREATED BY SIZE COMMENT
da269a070c7e About an hour ago /bin/sh -c apt-get -y install perl 43.13 MB
8ccd6d7bda0d About an hour ago /bin/sh -c apt-get update 37.81 MB
2fa927b5cdd3 5 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
<missing> 5 weeks ago /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/ 1.895 kB
<missing> 5 weeks ago /bin/sh -c rm -rf /var/lib/apt/lists/* 0 B
<missing> 5 weeks ago /bin/sh -c set -xe && echo '#!/bin/sh' > /u 701 B
<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:
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:
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:
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:
How do you expose a TCP port in an image?
Use the EXPOSE <port>
declaration in the image’s Dockerfile
. For example:
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:
In this case, bash
would be executed automatically when launching the container:
bash-4.3#
However, the user may still specify a command as the last argument to docker run
so that CMD
gets ignored.
bin dev home lib64 mnt proc run srv tmp var
boot 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:
In the above case, docker run
without a command argument will run /bin/bash --norc
but the latter may be optionally overridden:
bash-4.3# exit
exit
GNU bash, version 4.3.42(1)-release (x86_64-pc-linux-gnu)
Check the **Running an Image** section to see how to
override 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:
total 72
drwxr-xr-x 33 root root 4096 Jul 2 16:47 .
drwxr-xr-x 33 root root 4096 Jul 2 16:47 ..
-rwxr-xr-x 1 root root 0 Jul 2 16:47 .dockerenv
drwxr-xr-x 2 root root 4096 May 25 23:11 bin
drwxr-xr-x 2 root root 4096 Apr 12 20:14 boot
drwxr-xr-x 5 root root 380 Jul 2 16:47 dev
drwxr-xr-x 45 root root 4096 Jul 2 16:47 etc
...
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:
Fetch file from URL: In this case
Unpack archive file: In this case .tar
, .tar.gz
, etc. For example:
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:
Multiple label may also appear in the same line. For example:
The labels can be extracted using the docker inspect
command:
map[author:ernie release:1.2]
ernie
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:
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:
root@8883750fbf8b:/# ls -la | grep out
drwxrwxrwt 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:
root@e9c53b0b5906:/# cd myvolume
root@e9c53b0b5906:/myvolume# echo "Hello My Volume" >> hello.txt
root@e9c53b0b5906:/myvolume# exit
Even though we have stopped the container by exiting it, we can still find the file:
/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:
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:
80/tcp -> 0.0.0.0:32769
You may also specify a specific port number if there are many that are exposed:
# docker port apache_container 80
0.0.0.0:32769
How do you find out a container’s internal IP address?
172.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:
export SERVER_IP=`docker inspect -f {{.NetworkSettings.Networks.bridge.IPAddress}} server`
docker 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: