Tips and tricks with Docker
I’ll admit that a lot of this surprised me when I first learned of it, even though the information is readily available in Docker’s own documentation. How many of these things did you know about when using Docker?
Default language images are huge!
Did you know that when you build a container from an image such as ruby:2.4 or go:1.8, you are actually installing a whole lot of packages you likely may not need. You’ll get git, python, pip, node, and a good portion of the rest of a Debian OS install. This inflates the size of your container and, if you’re not careful, you will be deploying all of these things into production too.
Instead, try to spend some time building an Alpine image (e.g. ruby:2.4-alpine) and piecing together the dependencies you need. If that’s too much, try the slim image instead (e.g. python:3.5-slim) and work from there. If you decide you need some extra tools for convenience, you can still install them while the container is running and they’ll be gone the next time you rebuild.
It’s so much easier to clean up after yourself now
Since version 1.13 you can now run docker system prune to clean up all of your unused containers and images. Your hard drive will rest well at night. :)
Uninstalling things in your container might not work how you expect
It’s tempting to complicate your Dockerfile so that you can keep the eventual size down. You might try running various cleanup commands and deleting unused dependencies before running the final command.
Each individual directive in a Dockerfile creates a new layer, and the end result is a layer containing a culmination of all those changes. Adding RUN apk del x y z before your CMD isn’t going to make your container smaller. This means you might be tempted to run every command in one line instead, at the cost of making your Dockerfile hard to follow.
Instead, you can use one container to generate a new container, instead of building your app and then running it at the same time. The resulting build artifact will be much smaller and won’t contain anything that isn’t necessary for production. This is especially good with compiled languages and statically linked dependencies.