Tips for writing Dockerfiles
We've been using docker on our projects recently to ease development and deployment processes. Here are a few tips based on what we learned building and maintaining docker infrastructure for production.
Docker image layers
In the early days of docker, there used to exist a pretty low number limit of layers: it was equal to the Ultimate Question of Life, the Universe, and Everything or if you prefer, the limit of aufs layers (42). That docker limitation has now been overcome, and the layer limit has been increased to 127.
Although the limitation has been increased, it is still a good practice to avoid creating excessive amounts of layers.
Each instruction or step that is executed during a
docker build run, creates a new layer and we want to minimize the amount of layers where it makes sense.
Using instructions with multiple operations
RUN try to concatenate several commands together making them make sense as a unit, that is, if you are installing Nginx, use the layer to install Nginx only and remove all the temporary files, to minimize space used by the layer. For example:
Note that we remove all the temporary files before ending the command line for the
RUN instruction because once a layer is committed, it keeps the content forever. If the content is removed in the next step/instruction the resulting image will not free up the space.
EXPOSE, you can specify as many ports as you want in a single line. For example:
VOLUME, specify all the volumes in the same line as an array. For example:
A couple of extra tips
ENV you can specify multiple environment variables in a single line resulting in a single layer. For example:
The use of
WORKDIR will result in the creation of a directory, not only as a mount point reference in the case of
VOLUME, but also as a physical directory in the filesystem of the image. That is:
will create a docker image that has 3 new directories
/APP1 of which two of them can be mounted with
docker run -v ~/:/newdir imagename or
docker run -v ~/:/app imagename and a third directory that is set as the CWD (current working directory) of the runtime.
We hope that you can take these practices and incorporate them into your own code to slim down your Dockerfiles. Got any other suggestions? Tweet them to us: @spantreellc