"Tips and Tricks of the Docker Captains", YouTube video, published by "Docker" on 3 Nov 2017. Available: https://www.youtube.com/watch?v=1vgi51f0tCk
On keeping containers small:
- Alpine image.
- If need Debian, there are the debian:-slim images.
- Centos:6.9 is 70MB.
On mounting volumes:
- Docker mounts volumes at the inode level.
- If mounting files instead of directories, changes to mount source (the file) will not propogate to mount target. This is because when editors save changes to a file, it saves the changed file to a new inode, while the inode mounted by docker remains.
Cleaning up:
-- doesn't work withdocker images prune
17.09.1-ce-mac42 (21090)
; must rundocker system prune
(also safer)docker network prune
docker volume prune
docker system prune
-- executes all of the above
Keep build contexts minimal:
docker build -t <container_name> .
sets the build context to the current directory (.
).- This copies all the contents of the current directory into the build container, for use by the
docker build
process. - Makes builds slow. Keep build context as small as possible. Mount large static dependencies such as data stores etc.
docker build
cleans up the build context automatically after the image is built -- keeping build contexts small is to speed up the build process.
Cache-conscious Dockerfiles
- Each INSTRUCTION line in the Dockerfile creates an intermediary image.
- The result of each INSTRUCTION line is cached. If the INSTRUCTION line changes, the cache is ignored and the INSTRUCTION is rebuilt.
- Consequently, good practice to:
- Have as few INSTRUCTION lines as possible. Concatenate INSTRUCTIONS such as
RUN apt-get install xxx yyy zzz
- Write INSTRUCTION lines so that cached intermediary images do not have to be rebuit. Group INSTRUCTIONS that change regularly separately from static INSTRUCTIONS. For example, copying source and data sets should occupy their own INSTRUCTION line, separate from
RUN apt-get update && apt-get install xxx
.
- Have as few INSTRUCTION lines as possible. Concatenate INSTRUCTIONS such as
On container configuration:
- Do not require containers to start in sequence.
- If necessary, containers must not fail if dependencies fail.
wait
scripts are available to check if dependencies are available
Healthchecks
- Avoid using
curl
to do HEALTHCHECKS. Adds many dependencies that can be avoided. - There are scripts available to circumvent the curl healthcheck.
- See https://blog.sixeyed.com/docker-healthchecks-why-not-to-use-curl-or-iwr/
Read-only containers
- Reduce attack surface.
docker run --read-only --tmpfs
- Can mount volumes if need to write to specific files.
Set user space explicitly
- Reduce attack surface.
FROM debian:jessie
RUN group add -r <mygroup> && useradd -r -g <mygroup> <myuser>
[…]
USER <myuser>
OR use NOBODY:NOBODY
USER nobody
Docker-in-Docker (DinD)
- Avoid. Large attack surface; doesn't work very well.
- If must use, there is a
docker:dind
image. - No security benefit.
Running a GUI
# From Jessie Frozelle: Docker containers on Desktop
docker run -d -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY --device /dev/snd:/dev/snd --name spotify jess/spotify
Docker access == Root access to host
- Giving access to run docker on a system is essentially giving root access to a docker host system.
- Can mount any folder and write to it.
- Can mount any folder and run a binary to escape the container.
- (Is this also true for macOS and Windows containers?)