Docker: Tips and Tricks

root's picture

So I finally got a bit into docker because everybody is talking about it.
I will pass over the installation part because it is not that difficult (easier than windows install actually: next, next, finish) and go straight to the interesting part: using docker commands.

By default (relying on my tests only), docker is creating containers on top of:

- windows - hyper-v
- macos - hyperkit
- linux - mnt namespace (a fancy chroot :)
This can differ, depending on docker versions and/or operating system.

Dictionary:

Image - an inert, immutable, file that's essentially a snapshot of a container. Images are created with the build command, and they'll produce a container when started with run. Images are stored in a Docker registry such as registry.hub.docker.com. Because they can become quite large, images are designed to be composed of layers of other images, allowing a miminal amount of data to be sent when transferring images over the network.
Container - is an instance of a class—a runtime object. They're lightweight and portable encapsulations of an environment in which to run applications.

How to create and list a docker container named webone with nginx inside and host's port 8000 redirects to container's port 80:

In this example, nginx image (that will be used to start and run our container) is not available locally so it will be downloaded first.
Command: $ docker run --detach --publish=HOST_PORT:CONTAINER_PORT --name=CONTAINER_NAME IMAGE

Command execution and output:

[osx@mini ~]$ docker run --detach --publish=8000:80 --name=webone nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
f7e2b70d04ae: Pull complete 
08dd01e3f3ac: Pull complete 
d9ef3a1eb792: Pull complete 
Digest: sha256:98efe605f61725fd817ea69521b0eeb32bef007af0e3d0aeb6258c6e6fe7fc1a
Status: Downloaded newer image for nginx:latest
5045d980f2e031c2981001fb93687cb79c0f290f32584eeaac0337dda50545bc
[osx@mini ~]$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
174874390d27        nginx               "nginx -g 'daemon of…"   9 seconds ago       Up 8 seconds        0.0.0.0:8000->80/tcp   webone

Now, a second nginx container will be created very fast because the nginx image is already on our system:

[osx@mini ~]$ docker run --detach --publish=8001:80 --name=webtwo nginx
163e58f21a6722bf36a6b5503c1e7f442316a7f40dae81cc1e2adf8002fbf4f4
[osx@mini ~]$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
163e58f21a67        nginx               "nginx -g 'daemon of…"   4 seconds ago       Up 2 seconds        0.0.0.0:8001->80/tcp   webtwo
174874390d27        nginx               "nginx -g 'daemon of…"   3 minutes ago       Up 3 minutes        0.0.0.0:8000->80/tcp   webone

How to connect to a container as root:

As you may observe, in this example we connect to the user by UID or by it's name. The UID 0 means root.
Command: docker exec -u UID_OR_USERNAME -it CONTAINER_NAME bash

Command execution and output:

[osx@mini ~]$ docker exec -u 0 -it webone bash
root@174874390d27:/# whoami
root

How to connect to a container with a non privileged user (meaning, not root):

Now that we are inside, we can see if we have other users. I guess nginx will be there but it is fun to check first.
Command: $ docker exec -u UID_OR_USERNAME -it CONTAINER_NAME bash

Command execution and output:

root@174874390d27:/# cat /etc/passwd | grep -i nginx
nginx:x:101:101:nginx user,,,:/nonexistent:/bin/false
root@174874390d27:/# exit
exit
[osx@mini ~]$ docker exec -u nginx -it webone bash
nginx@174874390d27:/$ whoami
nginx

How to remove a docker container:

In order to remove one docker container, you will see that you have to stop it first.
Command: $ docker rm CONTAINER_NAME

Command execution and output:

[osx@mini ~]$ docker rm webtwo
Error response from daemon: You cannot remove a running container 163e58f21a6722bf36a6b5503c1e7f442316a7f40dae81cc1e2adf8002fbf4f4. Stop the container before attempting removal or force remove
[osx@mini ~]$ docker stop webtwo
webtwo
[osx@mini ~]$ docker rm webtwo
webtwo
[osx@mini ~]$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
174874390d27        nginx               "nginx -g 'daemon of…"   35 minutes ago      Up 35 minutes       0.0.0.0:8000->80/tcp   webone

How to view and tail the output of a container log:

Command: $ docker logs -f --tail 10 CONTAINER

How to search trough images:

Images are used to create our containers with whatever we want for it to run. For example, earlier we have used a linux image with nginx preinstalled to create our nginx container.
Now, I want to create one container with apache but using "apache" won't have the same result as using "nginx" because there is no such image named "apache". See below.
Command: $ docker search whatever

Command execution and output:

[osx@mini ~]$ docker run --detach --publish=8002:80 --name=webthree apache
Unable to find image 'apache:latest' locally
docker: Error response from daemon: pull access denied for apache, repository does not exist or may require 'docker login'.
See 'docker run --help'.

In order to move forward, we need to see which image contains apache inside:

[osx@mini ~]$ docker search apache
NAME                                     DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
httpd                                    The Apache HTTP Server Project                  2368                [OK]                
tomcat                                   Apache Tomcat is an open source implementati…   2314                [OK]                
cassandra                                Apache Cassandra is an open-source distribut…   942                 [OK]                
maven                                    Apache Maven is a software project managemen…   821                 [OK]                
solr                                     Solr is the popular, blazing-fast, open sour…   640                 [OK]                
eboraas/apache-php                       PHP on Apache (with SSL/TLS support), built …   141                                     [OK]
apache/nifi                              Unofficial convenience binaries and Docker i…   114                                     [OK]
webdevops/php-apache-dev                 PHP with Apache for Development (eg. with xd…   99                                      [OK]
eboraas/apache                           Apache (with SSL/TLS support), built on Debi…   90                                      [OK]
webdevops/php-apache                     Apache with PHP-FPM (based on webdevops/php)    84                                      [OK]
apache/zeppelin                          Apache Zeppelin                                 81                                      [OK]
tomee                                    Apache TomEE is an all-Apache Java EE certif…   64                  [OK]                
groovy                                   Apache Groovy is a multi-faceted language fo…   63                  [OK]                
nimmis/apache-php5                       This is docker images of Ubuntu 14.04 LTS wi…   60                                      [OK]
apacheignite/ignite                      Apache Ignite In-Memory docker image.           50                                      [OK]
bitnami/apache                           Bitnami Apache Docker Image                     49                                      [OK]
zabbix/zabbix-web-apache-mysql           Zabbix frontend based on Apache web-server w…   24                                      [OK]
linuxserver/apache                       An Apache container, brought to you by Linux…   21                                      
apache/nutch                             Apache Nutch                                    16                                      [OK]
1and1internet/ubuntu-16-apache-php-7.0   ubuntu-16-apache-php-7.0                        13                                      [OK]
webdevops/apache                         Apache container                                12                                      [OK]
antage/apache2-php5                      Docker image for running Apache 2.x with PHP…   12                                      [OK]
lephare/apache                           Apache container                                4                                       [OK]
newdeveloper/apache-php-composer         apache-php-composer                             3                                       
newdeveloper/apache-php                  apache-php7.2                                   3

So our target image with apache preinstalled is called "httpd". Cute.

[osx@mini ~]$ docker run --detach --publish=8002:80 --name=webthree httpd
Unable to find image 'httpd:latest' locally
latest: Pulling from library/httpd
f7e2b70d04ae: Already exists 
84006542c688: Pull complete 
dae6fe3c5e81: Pull complete 
33fc493aff90: Pull complete 
9a4113020573: Pull complete 
Digest: sha256:20ead958907f15b638177071afea60faa61d2b6747c216027b8679b5fa58794b
Status: Downloaded newer image for httpd:latest
a0bedb28a484efd20e307c8d356006c4ee11bde7c5f8b7cdc3b24414267adc9b
[osx@mini ~]$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
a0bedb28a484        httpd               "httpd-foreground"       9 seconds ago       Up 11 seconds       0.0.0.0:8002->80/tcp   webthree
6cd76ae14202        nginx               "nginx -g 'daemon of…"   8 minutes ago       Up 5 minutes        0.0.0.0:8001->80/tcp   webtwo
174874390d27        nginx               "nginx -g 'daemon of…"   About an hour ago   Up 5 minutes        0.0.0.0:8000->80/tcp   webone

How to list all containers (including inactive ones):

If you stop an image and do ls, you will notice that the stopped container is no more there.
So, how do you list the stopped containers?
Commands (same output for both):
$ docker container ls -a
$ docker ps -a

Command execution and outuput:

08:37:47 root@service:~# docker ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
ff3a6cb398b2        mysql               "docker-entrypoint.s…"   8 hours ago         Up 8 hours          0.0.0.0:3306->3306/tcp, 33060/tcp   dbone
85b449e4c44a        httpd               "httpd-foreground"       8 hours ago         Up 8 hours          0.0.0.0:8001->80/tcp                webtwo
b4fba86f5f7b        nginx               "nginx -g 'daemon of…"   8 hours ago         Up 8 hours          0.0.0.0:8000->80/tcp                webone
08:37:53 root@service:~# docker stop webtwo
webtwo
08:38:09 root@service:~# docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
ff3a6cb398b2        mysql               "docker-entrypoint.s…"   8 hours ago         Up 8 hours          0.0.0.0:3306->3306/tcp, 33060/tcp   dbone
b4fba86f5f7b        nginx               "nginx -g 'daemon of…"   8 hours ago         Up 8 hours          0.0.0.0:8000->80/tcp                webone
08:38:14 root@service:~# docker container ls -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS                               NAMES
ff3a6cb398b2        mysql               "docker-entrypoint.s…"   8 hours ago         Up 8 hours                  0.0.0.0:3306->3306/tcp, 33060/tcp   dbone
85b449e4c44a        httpd               "httpd-foreground"       8 hours ago         Exited (0) 10 seconds ago                                       webtwo
b4fba86f5f7b        nginx               "nginx -g 'daemon of…"   8 hours ago         Up 8 hours                  0.0.0.0:8000->80/tcp                webone

How to list only inactive containers:

Command:$ docker container ls -f 'status=exited'
NOTE: with -f you can list: created, restarting, running, removing, paused, exited and dead

Command execution and outuput:

08:39:34 root@service:~# docker container ls -f 'status=exited'
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS                               NAMES
85b449e4c44a        httpd               "httpd-foreground"       8 hours ago         Exited (0) 10 seconds ago                                       webtwo

How to remove all stopped containers:

Command: $ docker rm $(docker container ls -a | grep Exited | awk '{print $1}' | xargs)

Example:

[osx@mini ~]$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                    PORTS                  NAMES
18b5f53a2333        nginx               "ls -la /etc"            20 hours ago        Exited (0) 20 hours ago                          reverent_bhaskara
9bcc734d62c8        nginx               "cat /etc/debian_rel…"   20 hours ago        Exited (1) 20 hours ago                          inspiring_elion
1979dd8ad04d        httpd               "cat /etc/debian_rel…"   20 hours ago        Exited (1) 20 hours ago                          condescending_archimedes
55df2d566bc4        httpd               "ls -la"                 20 hours ago        Exited (0) 20 hours ago                          youthful_aryabhata
323373b9c5cb        nginx               "ls -la"                 20 hours ago        Exited (0) 20 hours ago                          reverent_chaplygin
a0bedb28a484        httpd               "httpd-foreground"       21 hours ago        Up 21 hours               0.0.0.0:8002->80/tcp   webthree
6cd76ae14202        nginx               "nginx -g 'daemon of…"   21 hours ago        Up 21 hours               0.0.0.0:8001->80/tcp   webtwo
174874390d27        nginx               "nginx -g 'daemon of…"   22 hours ago        Up 21 hours               0.0.0.0:8000->80/tcp   webone
[osx@mini ~]$ docker rm $(docker container ls -a | grep Exited | awk '{print $1}' | xargs)
18b5f53a2333
9bcc734d62c8
1979dd8ad04d
55df2d566bc4
323373b9c5cb
[osx@mini ~]$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
a0bedb28a484        httpd               "httpd-foreground"       21 hours ago        Up 21 hours         0.0.0.0:8002->80/tcp   webthree
6cd76ae14202        nginx               "nginx -g 'daemon of…"   21 hours ago        Up 21 hours         0.0.0.0:8001->80/tcp   webtwo
174874390d27        nginx               "nginx -g 'daemon of…"   22 hours ago        Up 21 hours         0.0.0.0:8000->80/tcp   webone

How to rename a container:

Command: $ docker container rename CURRENT_NAME_OR_ID NEW_NAME

Example:

root@uranus:~# docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
5c334ea295d4        debian              "bash"              8 hours ago         Up 2 seconds                            recursing_morse
root@uranus:~# docker container rename 5c334ea295d4 mediashow
root@uranus:~# docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
5c334ea295d4        debian              "bash"              8 hours ago         Up 40 seconds                           mediashow

How to change the restart policy of a container (e.g. make it start automatically on reboot):

19:18:15 root@service:~# docker update --restart=always repo
repo

How to see the history of an image:

This way you can see where the image got it's size and if you are the maintainer of that image, you can improve the steps to make it smaller.

01:25:17 root@service:~# docker history consul
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
df36de474d54        3 weeks ago         /bin/sh -c #(nop)  CMD ["agent" "-dev" "-cli…   0B                  
<missing>           3 weeks ago         /bin/sh -c #(nop)  ENTRYPOINT ["docker-entry…   0B                  
<missing>           3 weeks ago         /bin/sh -c #(nop) COPY file:2fc9ee792fd5d6e2…   3.86kB              
<missing>           3 weeks ago         /bin/sh -c #(nop)  EXPOSE 8500 8600 8600/udp    0B                  
<missing>           3 weeks ago         /bin/sh -c #(nop)  EXPOSE 8301 8301/udp 8302…   0B                  
<missing>           3 weeks ago         /bin/sh -c #(nop)  EXPOSE 8300                  0B                  
<missing>           3 weeks ago         /bin/sh -c #(nop)  VOLUME [/consul/data]        0B                  
<missing>           3 weeks ago         /bin/sh -c test -e /etc/nsswitch.conf || ech…   17B                 
<missing>           3 weeks ago         /bin/sh -c mkdir -p /consul/data &&     mkdi…   0B                  
<missing>           3 weeks ago         /bin/sh -c set -eux &&     apk add --no-cach…   103MB               
<missing>           3 weeks ago         /bin/sh -c addgroup consul &&     adduser -S…   4.84kB              
<missing>           3 weeks ago         /bin/sh -c #(nop)  ENV HASHICORP_RELEASES=ht…   0B                  
<missing>           3 weeks ago         /bin/sh -c #(nop)  ENV CONSUL_VERSION=1.4.4     0B                  
<missing>           5 weeks ago         /bin/sh -c #(nop)  MAINTAINER Consul Team <c…   0B                  
<missing>           5 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B                  
<missing>           5 weeks ago         /bin/sh -c #(nop) ADD file:aa17928040e31624c…   4.21MB              
01:25:25 root@service:~# docker images | grep -i consul
consul                                     latest              df36de474d54        3 weeks ago         107MB

How to change the hostname of a running container:

NOTE: this is not persistent - after you stop/start the container, this change will be reversed.
Commands:
$ docker inspect -f '{{ .State.Pid }}' CONTAINER_NAME_OR_ID
$ nsenter --target PID_RESULT_FROM_PREVIOUS_COMMAND --uts
$ hostname NEW_HOSTNAME; exit

Example:

root@uranus:~# docker exec -ti mediashow bash
root@5c334ea295d4:/# hostname
5c334ea295d4
root@5c334ea295d4:/# exit
root@uranus:~# docker inspect -f '{{ .State.Pid }}' 5c334ea295d4
2464
root@uranus:~# nsenter --target 2464 --uts
root@5c334ea295d4:~# hostname mediashow
root@5c334ea295d4:~# logout
root@uranus:~# docker exec -ti mediashow bash
root@mediashow:/#

Useful links:

Docker Machine
Docker glossary

Thou shalt not steal!

If you want to use this information on your own website, please remember: by doing copy/paste entirely it is always stealing and you should be ashamed of yourself! Have at least the decency to create your own text and comments and run the commands on your own servers and provide your output, not what I did!

Or at least link back to this website.

Recent content

root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root