This document provides lessons learned from running Docker in production. Key lessons include:
- Do not use the Docker "latest" tag and instead specify exact versions to ensure repeatability.
- Derive Docker images from specific base images and update them regularly to get security fixes.
- Plan for processes like supervisors that handle signals and allow containers to exit gracefully.
- Use microlabeling to annotate images with metadata about their origin and version.
- Parameterize Dockerfiles and configurations to separate configurable values from code.
2. Nicholas Dille
Ehemann, Vater, Geek, Autor
Microsoft MVP seit 2010
Docker Captain seit 2017
DevOps Engineer @ Haufe-Lexware
http://dille.name/blog
@NicholasDille
4. Do not use latest
Latest is like buying a pig in a poke
ubuntu:latest = ubuntu:xenial until new LTS
ubuntu:xenial = ubuntu:xenial-20180123 until new monthly patch
Latest breaks repeatability
Derive from specific version
Update regularly, fail early
5. Do not use latest
Dockerfile
FROM ubuntu
#...
Dockerfile
FROM nginx
#...
Dockerfile
FROM ubuntu:xenial-20180123
#...
Dockerfile
FROM nginx:1.12.1
#...
6. Derive from code
Using community images is also like buying a pig in a poke
h1kkan/jenkins-docker is has lots of useful stuff
Community images may not receive updates
Community images may follow undesirable paths
Fork Dockerfile and build yourself
7. Plan for PID 1
Even containerized services want to exit gracefully
Only containerized PID 1 received signals
Several processed require an init process
Choices include supervisor, dumb-init, tini
Use exec when starting from scripts
Isolate in sidekicks
8. Plan for PID 1
Dockerfile
FROM ubuntu:xenial-20180123
RUN apt update
&& apt install -y nginx
ADD entrypoint.sh /
ENTRYPOINT /entrypoint.sh
entrypoint.sh
#!/bin/bash
#...
exec nginx -g daemon=off;
9. Plan for PID 1
Dockerfile
FROM ubuntu:xenial-20180123
RUN apt update
&& apt install -y
nginx
supervisor
ADD nginx.conf /etc/supervisor/conf.d/
ENTRYPOINT supervisord
nginx.conf
[program:nginx]
command=nginx -g daemon=off;
10. Use microlabeling
Mark images with information about origin
Easily find corresponding code
Use image annotations by the OCI
Deprecated: https://label-schema.org
11. Use microlabeling
Dockerfile
FROM ubuntu:xenial-20180123
LABEL
org.opencontainers.image.created=“2018-01-31T20:00:00Z+01:00“
org.opencontainers.image.authors=“nicholas@dille.name“
org.opencontainers.image.source=“https://github.com/nicholasdille/docker“
org.opencontainers.image.revision=“566a5e0“
org.opencontainers.image.vendor=“Nicholas Dille“
#...
15. Readability beats size
Myth: More layers reduce access time
My own tests prove otherwise
Layers improve performance on pull (parallel downloads)
One layer per installed tool
Separate functionality into chains of images
dind dind-gocd-agent
linux-agent linux-agent-gocd
linux-agent-jenkins
16. Tips and tricks
Building behind a proxy
docker build
--build-arg http_proxy
--build-arg https_proxy
--build-arg no_proxy
.
Running behind a proxy
docker run -it
--env http_proxy
--env https_proxy
--env no_proxy
ubuntu:xenial-20180123
Implicit pull on build
docker build --pull .
Automatic cleanup
docker run -it --rm ubuntu:xenial
Derive dynamically
ARG VERSION=xenial-20180123
FROM ubuntu:${VERSION}
17. Learn your own lessons
Do my lessons apply to you?
Automate
Do CI/CD
Containers are just one option
Link to code
https://github.com/nicholasdille/Sessions/tree/master/2018-01-
31%20Docker%20%40%20Devsmeetup