Docker packaging is complicated, and you can’t afford to screw up production
You’re about to ship your Python application into production using Docker: your images are going to be critical infrastructure.
And that means you need to follow best practices—if you don’t, you risk wasting quite a lot of money:
- You don’t want to waste hours every week waiting for slow builds.
- Or even worse, you might have a production outage or security breach, costing your company orders of magnitude more money.
So how can you ensure your Docker image packaging isn’t wasting your team’s time? How can you ensure you’re following best practices, for security, efficiency, and debuggability?
Doing your own research: difficult and time-consuming
Unfortunately, while the information you need is out there on the Internet, actually discovering best practices is slow, tricky work.
You’ll need to filter out the ignorant, broken, and confused advice from people who don’t really know what they’re doing.
For exampe, do a quick search on Google or DuckDuckGo, and you’ll find
- Have you run your container as root, even though that’s insecure.
- Don’t bother installing security updates, let alone explaining how Docker’s build caching interacts badly with security updates.
You’ll also need to filter out all the obsolete and out-of-date advice. For example, the multi-stage build support added in Docker 17.05 obsoletes much of the previous advice on creating small images.
Finally, you’ll need to customize all the advice you find in order to apply it to Python applications.
For example, the Docker Best Practices page recommends using Alpine as a base image, which is fine advice for Go applications.
But it’s a bad idea if you’re using Python; due to the way binary wheels work, I’ve seen builds go from 30 seconds on Debain/Ubuntu to 15 minutes on Alpine when trying to install common packages like
In short, while you can do the research on your own, it will be expensive and time-consuming. And worse, you might miss some critical piece of advice and deploy an insecure image.
Best practices for Python, the fast way
You want to package your Python application for production with confidence, knowing you’ve implemented best practices that will save you time and money going forward.
You want secure images, fast builds, and operational correctness. You want to understand what you’re doing. And you want to have all the relevant best practices summarized in one place, so you can quickly ensure you’re doing the right thing.
That’s why I’ve created the Python on Docker Production Checklist. Based on a year’s worth of research, the checklist summarizes the best practices you need to know.
In particular, the checklist:
- Exclusively focuses on creating Docker images for Python applications that run in production.
- Includes over 35 different best practices, covering security, image size, fast builds, operational correctness, reproducibility, and more.
- For each best practice you’ll get:
- A quick explanation.
- A brief example of how to apply the best practice, when possible.
- Links to references and guides providing more in-depth information.
You can use the checklist to guide you through initial development of your image, or to review an existing image for correctness and potential improvements. And since you’ll be using it as a checklist, it’s short and to the point.
“I’ve been using the checklist… and it’s been absolutely fantastic”
What readers are saying:
“I’ve been using the checklist a lot over the last two weeks and it’s been absolutely fantastic.
Learning about multi-stage builds has meant I can combine a Django/React app into one Dockerfile. This also lead to me discovering compose build sections can target a named stage so now I’ve got local dev using the same Dockerfile, which is great.”
— George Hickman
|Python on Docker
|Ship faster with the|
Want the checklist for your whole team? 10-person team edition for $249.
Note: I prefer not to take money from teams working on projects for the military, prisons, fossil fuel extraction, surveillance, national security, or the like. If that applies to you, please don’t purchase this product.
April 27, 2020
- Added new best practice on timely security updates via automatic notifications.
- Switched some examples from shell session transcripts to
Dockerfileor shell script.
docker buildsupport for targeting named stages earlier in the checklist.
April 1, 2020
- Documented two-stage install with Poetry 1.0+.
- Added link to
February 24, 2020
Added many more examples:
- A smoke test.
- Passing in secrets with BuildKit.
- System package upgrade script for CentOS/RHEL.
- And a few more expanded examples here and there.
Hi, I’m Itamar Turner-Trauring.
I’ve been writing Python since 1999, and I first started using Docker in 2014, when I was part of a team that wrote one of the first distributed storage backends for Docker.
I’ve since built Telepresence, a remote development tool for Kubernetes that was adopted as a Cloud Native Computing Foundation sandbox project and has more than 2000 stars on GitHub. I’ve also deployed a number of production Python applications as Docker images.
Over the past year I’ve been researching Docker packaging for Python in production, resulting in a free guide elsewhere on this site, live training classes, an introductory book, a template implementing these best practices, and of course this checklist.