6. Dockerfile
• Automate image creation with docker build
• Place instructions for building image in Dockerfile
• Commands: FROM, COPY, RUN, etc…
• Uses the same run/commit/rm sequence as the
interactive approach
• More repeatable/shareable than the interactive
approach
*
7. Image Layers
• Each Dockerfile instruction generates a new layer
FROM busybox:latest
MAINTAINER brian
RUN touch foo
CMD ["/bin/sh"]
8c2e06607696
5bd9073989ff
0437ee5cf42c
350e4f999b25
8. Image Layers
• An image is a hierarchical list of layers
• Each layer has a reference to its parent
• Overall image size is the sum of the sizes of the
individual layers
• Each additional instruction you add to your
Dockerfile will only ever increase the size of your
image
*
9. Inspecting Layers
• View hierarchy of all local layers
• docker images --tree
• View hierarchy of image layers w/ command
• docker history <TAG>
• View all metadata for a specific layer
• docker inspect <TAG>
• View layer directly on disk
• /var/lib/docker/aufs*
* varies by platform
10. !"cf2616975b4a Virtual Size: 0 B
!"6ce2e90b0bc7 Virtual Size: 2.433 MB
!"8c2e06607696 Virtual Size: 2.433 MB Tags: busybox:latest
!"d6057c416142 Virtual Size: 2.433 MB
!"70714dda0cf8 Virtual Size: 2.448 MB Tags: foo:latest
$ docker run -it d6057c416142 /bin/sh
Images vs. Layers
• An image is just a tagged hierarchy of layers
• Every layer in an image is runnable
• Helpful when trying to debug Dockerfiles
12. $ docker images
REPOSITORY TAG IMAGE ID VIRTUAL SIZE
aa latest 5927ecad7beb 90.22 MB
bb latest 4f02d7398349 100.7 MB
cc latest f466548ecd34 95.47 MB
debian wheezy 1265e16d0c28 84.98 MB
Virtual Image Size
• ~370MB in images?
• Virtual size can be misleading, especially if images
have layers in common
16. Command Chaining
• Beware of creating unnecessary layers with your
Dockerfile commands
FROM debian:wheezy
WORKDIR /tmp
RUN wget -nv http://foo.com/someutil-v1.0.tar.gz
RUN tar -xvf someutil-v1.0.tar.gz
RUN mv /tmp/someutil-v1.0/someutil /usr/bin/someutil
RUN rm -rf /tmp/someutility-v1.0
RUN rm /tmp/someutility-v1.0.tar.gz
17. Command Chaining
• Chaining commands allows you to clean-up before
the layer is committed
FROM debian:wheezy
WORKDIR /tmp
RUN wget -nv http://foo.com/someutil-v1.0.tar.gz &&
tar -xvf someutil-v1.0.tar.gz &&
mv /tmp/someutil-v1.0/someutil /usr/bin/someutil &&
rm -rf /tmp/someutility-v1.0 &&
rm /tmp/someutility-v1.0.tar.gz
18. Clean-up After Yourself
• Try to remove any intermediate/temporary files that
you don't need in your final image
FROM debian:wheezy
RUN apt-get update &&
apt-get install -y curl wget git &&
apt-get clean &&
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
19. Flattening Images
• Can sometimes reduce size by combining layers
• docker export <id> | docker import -
• Lots of other tools and Docker proposals for combining image
layers
• https://github.com/dqminh/docker-flatten
• https://gist.github.com/vieux/6156567
• https://github.com/docker/docker/issues/6906
• Not really recommended
20. Pack Only What You Need
• Start with FROM scratch and package only the bins/libs you
need for your app
• Use cde to profile your app and identify dependencies
• Statically-linked binaries w/ no dependencies (C, Go, etc…)
• centurylink/golang-builder: helps compile statically-linked Go
apps and package in minimal Docker containers
• centurylink/ca-certs: base image that is just scratch plus the
standard root CA certificates (257 KB)
22. Image Cache
• All built or pulled layers are saved in the local image
cache
• Docker won’t rebuild an unchanged layer (unless you
force it to)
• Significant increase in build speed when iterating on
Dockerfile
• Cache is invalidated for a layer if either the Dockerfile
instruction or the parent layer is changed
*
23. Build Context
• The final argument to docker build is typically the
build context
• Allows you to inject local files into your image using
the COPY instruction
• Changes to copied files will also invalidate image
cache
• Dockerfile must be located within the build context
*
24. Top-to-Bottom
• Place the instructions least likely to change at the top
of your Dockerfile
• Make changes/additions at the bottom
• Place instructions you use across all of your images
(MAINTAINER) at the top so they can be re-used
across all images
25. .dockerignore
• Place .dockerignore in the root of build context with
list of file/directory patterns to be excluded from build
context
• Very much like .gitignore
• Helpful when copying the entire build context and
want to selectively ignore files
FROM busybox:latest
COPY . /somedir/
*
26. Beware of Idempotent Operations
• Instructions that may return different results
depending on when they are executed
• apt-get update, git clone, go get, etc…
• Cached layer may not contain what you expect
• Can use --no-cache flag with docker build to
ignore cache
• Use strategic command chaining to bust cache
27. • Updating branch name does NOT invalidate cache
Bust Cache with Chained Commands
WORKDIR /tmp
RUN git clone https://github.com/bdehamer/sample.git
RUN git checkout v1.0
WORKDIR /tmp
RUN git clone https://github.com/bdehamer/sample.git &&
git checkout v1.0
• Updating branch invalidates cache
29. ADD vs. COPY
• ADD & COPY instructions both add files/directories to
the container
• ADD can also handle URLs as a source and will
automatically extract archives
• COPY added in Docker 1.0 and only copies files/dirs
• Use COPY unless there is a specific feature of ADD you
absolutely need
30. Repeatable Image Builds
• Ideally, anyone should be able to build your
Dockerfile at any time and get the same result
• Vague dependencies can result in unpredictable
builds
RUN apt-get update && apt-get install -y hello
RUN apt-get update && apt-get install -y hello=2.8-4
vs
31. Shell Variables
• Each Dockerfile instruction is executed in a new
container with a new shell
• Don’t try
RUN export FOO=BAR
RUN cd /tmp
RUN su - someuser
• Instead use
ENV FOO=BAR or RUN FOO=BAR /some/command/that/needs_foo
WORKDIR /tmp
USER someuser
35. imagelayers.io
• Visualize images on the Docker Hub
• See layers shared between different images
• See the instruction for each layer
• Get information about image size
• Coming soon! Available now!
36. Additional Reading
• CenturyLink Labs Blog
• http://centurylinklabs.com
• Best Practices for Writing Dockerfiles
• https://docs.docker.com/articles/dockerfile_best-practices
• Squashing Docker Images - Jason Wilder
• http://jasonwilder.com/blog/2014/08/19/squashing-docker-images/
• Create the Smallest Possible Docker Container - Adriaan de Jonge
• http://blog.xebia.com/2014/07/04/create-the-smallest-possible-
docker-container/