Docker Captain Adrian Mouat will present a grab bag of tips and tricks for getting the most out of Docker. These tips are aimed at avoiding common pitfalls, addressing common misunderstandings and making common operations easier. Topics covered will include:
- Build Processes
- Security
- Volumes
- Databases
- Debugging and Maintenance
- Calling Docker from Docker
Whilst aimed primarily at new and intermediate users, even advanced users should pick up some new information. This talk will make your daily life with Docker easier!
3. Tricks of the Captains
● A hodgepodge of tricks from
members of the Docker Captains
Programme
● And other luminaries of
microservices and containers
5. Configure docker ps Output
Default output of docker ps (or docker container ls)
$ docker ps
CONTAINER ID IMAGE COMMAND ...
0f1f72c9aac0 nginx "nginx -g 'daemon ...
Takes up too much width, difficult to read
6. Configure docker ps Output
Solution is to use the --format argument
$ docker ps --format
"table {{.Names}}t{{.Image}}t{{.Status}}"
NAMES IMAGE STATUS
web nginx Up 25 minutes
https://docs.docker.com/engine/reference/commandline/ps/#formatting
7. Configure docker ps Output
Make it a permanent default by adding it to config.json
$ cat ~/.docker/config.json
{...
"psFormat":
"table {{.ID}}t{{.Names}}t{{.Image}}t{{.Status}}"}
https://docs.docker.com/engine/reference/commandline/cli/#configuration-file
s
8. File Mounting Gotcha
Beware when mounting a single file as a volume
$ cat index.html
Moby Rules!
$ docker run -d -p 8000:80
-v $PWD/index.html:/usr/share/nginx/html/index.html nginx
0cdacef2cbaea960f710d90900b23c57550aaf626ccd2752f3a9287b7e5
$ curl localhost:8000
Moby Rules!
9. File Mounting Gotcha
$ vi index.html
...
$ cat index.html
Gordon Rules!
$ curl localhost:8000
Moby Rules!
?
10. File Mounting Gotcha
Volumes are mounted at the inode level
Text editors save to a new inode
Solutions:
● mount parent directory
○ -v $PWD:/usr/share/nginx/html
● copy modified file
○ cp new.html index.html
● overwrite with >
○ echo “bla” > index.html
Thanks Antonis Kalipetis!
11. Cleaning Up
Delete “dangling” images (<none> images)
$ docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Deleted Images:
deleted:
sha256:708624719836212ccb681d5898a64ebfcc4569f37460537609f6db6
…
Total reclaimed space: 3.677 GB
12. Cleaning Up
Delete stopped containers$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
6e5033be3e106d04912fb91b966abc693b77ae47d85946190bdbe73c48112959
…
Total reclaimed space: 304.6 MB
$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
6e5033be3e106d04912fb91b966abc693b77ae47d85946190bdbe73c481129
59
…
Total reclaimed space: 304.6 MB
13. Cleaning Up
$ docker volume prune
WARNING! This will remove all volumes not used by at least one
container.
…
Total reclaimed space: 3.494 GB
$ docker network prune
WARNING! This will remove all networks not used by at least
one container.
Are you sure you want to continue? [y/N] y
Deleted Networks:
...
14. Cleaning Up
All in one$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
6e5033be3e106d04912fb91b966abc693b77ae47d85946190bdbe73c48112959
…
Total reclaimed space: 304.6 MB
$ docker system prune
WARNING! This will remove:
- all stopped containers
- all volumes not used by at least one container
- all networks not used by at least one container
- all dangling images
16. The Build Context
The . in
$ docker build -t myimage .
● Tarballed and sent to the Docker Daemon
● Don’t run a build from ~/ or Downloads!
● Use .dockerignore to exclude large directories
17. Don’t Bust the Build Cache
To keep builds fast, add dependencies before
source code in Dockerfiles
...
COPY ./ /usr/src/
RUN npm install
...
...
COPY package.json
/usr/src/
RUN npm install
COPY ./ /usr/src/
...
18. Minimal Images
● Good for security
○ Less software that can be exploited
● Good for distribution
○ Faster updates, less network costs
20. Minimal Images
● Scratch and static binaries
FROM rust:1.20 as builder
…
RUN cargo build --release --target x86_64-unknown-linux-musl
FROM scratch
COPY --from=builder /.../release/mybin /mybin
USER 65534
CMD ["/mybin"]
21. Beware of “latest”
● Nothing special about tag
○ Not guaranteed to be “new”
○ Not guaranteed to exist
Default used when no tag specified
docker push/pull/build myimage ==
docker push/pull/build myimage:latest
22. Use Meaningful Tags
● Semantic versioning
○ docker build -t myimage:1.2.1 .
● Git hash
○ docker tag myimage:1.2.1
myimage:$(git rev-parse --short HEAD)
Make it obvious what is running in production!
23. And Labels for the Rest
$ docker build --label
org.opencontainers.image.created=
"$(date --rfc-3339=s)" -t myimage .
...
$ docker inspect
-f "{{json .ContainerConfig.Labels}}" myimage
{"org.opencontainers.image.created":"2017-10-05
16:21:00+01:00"}
See Annotations in the OCI image spec
and Gareth Rushgrove on why standard metadata is important
25. Start-up Dependably
● Do not require containers to start in sequence
● If a container depends on another service:
○ It should wait for that service
○ Do not crash - back off
● Do this in application code
○ or start-up script if you can’t
See 12 Fractured Apps by Kelsey Hightower
26. Shutdown Gracefully
When Docker stops a container, it will:
● Send the container a SIGTERM signal
● Wait 10s for the container to stop
● Hard kill the container with a SIGKILL
27. Shutdown Gracefully
Proper handling of SIGTERM will mean:
● The application gets a chance to “tidy up”
○ close network connections, sockets, handles
○ write data to file or database
○ output to log
● Faster shutdown of the container
Sreenivas Makam on Docker Features for Handling Container Death
28. Shutdown Gracefully
To ensure your application receives signals either:
● Run it as PID 1
○ Use exec in any start-up scripts
● Or forward signals to it
○ tini can help https://github.com/krallin/tini
● Prefer node to npm for starting node.js apps
○ Bret Fisher Node and Docker Good Defaults
29. Healthchecks
Used by Docker to determine “health” of container
FROM nginx
RUN apt-get update && apt-get install -y curl
HEALTHCHECK --interval=10s --timeout=3s
CMD curl -f http://localhost/ || exit 1
Thanks Laura Frank!
30. Healthchecks
Used by Docker to determine “health” of container
FROM nginx
RUN apt-get update && apt-get install -y curl
HEALTHCHECK --interval=10s --timeout=3s
CMD curl -f http://localhost/ || exit 1
31. Healthchecks
Give better status output
$ docker ps
CONTAINER ID ... STATUS
79616fdd4308 Up 3 seconds (health: starting)
$ docker ps
CONTAINER ID ... STATUS
79616fdd4308 Up 16 seconds (healthy)
32. Healthchecks
● Docker Swarm Mode will only route to healthy
containers
○ Essential for zero-downtime deploys
● Healthcheck event for integration with other
services
33. Healthchecks
● Note command runs in the container
○ Not on the host
● Using curl is a good start but
○ Extra dependency
○ Can be limiting
○ Consider writing bespoke tool
Elton Stoneman on Docker Healthchecks
Thanks Michael Irwin!
35. Read Only Filesystem
An easy way to improve security
$ docker run -d --name n1 --read-only -p 8000:80
--tmpfs /var/run --tmpfs /var/cache/nginx nginx
c1da395bec73ef7933fecb6d8d821140ce203c426c433e5102d25e46cdb66
$ docker exec n1 /bin/bash -c
'echo "HACKED" > /usr/share/nginx/html/index.html'
/bin/bash: /usr/share/nginx/html/index.html: Read-only file
system
36. Don’t Run as Root
Set a USER in Dockerfiles e.g:
FROM debian
RUN groupadd -r mygroup && useradd -r -g mygroup myuser
…
USER myuser
Or use the nobody user
37. Don’t Run as Root
Sometimes need to change user at run-time
sudo works, but has a drawback:
$ docker run debian-with-sudo sudo -u nobody ps ax
PID TTY STAT TIME COMMAND
1 ? Rs 0:00 sudo -u nobody ps ax
7 ? R 0:00 ps ax
38. Don’t Run as Root
Instead use gosu by Tianon Gravi
$ docker run debian-with-gosu gosu nobody ps ax
PID TTY STAT TIME COMMAND
1 ? Rs 0:00 ps ax
https://github.com/tianon/gosu
40. Docker-in-Docker
● A lot of people want to run Docker in Docker
○ Often for CI/CD
● Normally this is a bad ideaTM
○ Issues with filesystems
○ Also caching, image stores
Jérôme Petazzoni Do Not Use DinD For CI
41. Docker-in-Docker
Instead, mount the Docker socket:
$ docker run
-v /var/run/docker.sock:/var/run/docker.sock
docker
docker ps
CONTAINER ID IMAGE COMMAND ...
8bdba5bc5c7a docker "docker-entrypoint.sh" ...
42. Docker-in-Docker
If you really need true DinD
$ docker run --privileged --name dind -d docker:dind
4b78ae49d77dcf3c2e169c9e4440ace0813676f76e998f0aea2ef065a4b
$ docker run --link dind:docker docker docker run -d nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
...
$ docker run --rm --link dind:docker docker docker ps
CONTAINER ID IMAGE COMMAND ...
983cd6cb5a82 nginx "nginx -g 'daemon off" ...
43. Docker and GUIs
You can run GUI apps in containers!
$ docker run -d
-v /tmp/.X11-unix:/tmp/.X11-unix
-e DISPLAY=unix$DISPLAY
--device /dev/snd:/dev/snd
--name spotify
jess/spotify
Jessie Frazelle Docker Containers on the Desktop
46. References
Good Defaults for Node and Docker - Bret Fisher
12 Fractured Apps - Kelsey Hightower
Least Privilege Containers - Nathan McCauley and Diogo Monica
Gosu - sudo for containers by Tianon Gravi
tini - minimal init system for containers by Thomas Orozco
Docker Containers on the Desktop - Jessie Frazelle
47. References
Docker Features for Handling Container Death and Resurrection by Sreenivas Makam
Creating Effective Docker Images - Abby Fuller, DockerConEU 2017
Multi-stage builds - Alex Ellis
Do Not Use DinD For CI - Jérôme Petazzoni
Docker Healthchecks - Elton Stoneman
Annotations in the OCI image spec
Thanks to all the captains for discussions!