Production-ready Docker images

Docker packaging guide for Python


  1. Broken by default: why you should avoid most Dockerfile examples
    Most Dockerfile examples you’ll find on the Web are broken. And that’s a problem.

  2. The best Docker base image for your Python application
    Ubuntu? Official Python images? Alpine Linux? Here’s how to choose a good base image.


  1. Avoiding insecure images from Docker build caching
    Docker’s layer caching is great for speeding up builds—but you need to be careful or it’ll cause you to have insecure dependencies.

  2. Less capabilities, more security: minimizing privilege escalation in Docker
    To reduce the security risk from your Docker image, you should run it as a non-root user. You should also reduce it capabilities: learn what, why, and how.

  3. Docker build secrets, the sneaky way
    When you’re building Docker images you often need some secrets: a password, an SSH key. For now, Docker lacks a good mechanism to pass in secrets in a secure way, which means you need to get sneaky.

Fast builds, small images

  1. Faster Docker builds with pipenv, poetry, or pip-tools
    Installing dependencies separately from your code allows you to take advantage of Docker’s layer caching. Here’s how to do it with pipenv, poetry, or pip-tools.

  2. Elegantly activating a virtualenv in a Dockerfile
    How to activate a virtualenv in a Dockerfile without repeating yourself—plus, you’ll learn what activating a virtualenv actually does.

  3. Multi-stage builds #1: Smaller images for compiled code
    You’re building a Docker image for a Python project with compiled code (C/C++/Rust/whatever), and somehow without quite realizing it you’ve created a Docker image that is 917MB… only 1MB of which is your code!

  4. Multi-stage builds #2: Python specifics—virtualenv, –user, and other methods
    Now that you understand multi-stage builds, here’s how to implement them for Python applications.

  5. Multi-stage builds #3: Why your build is surprisingly slow, and how to speed it up
    Multi-stage builds give you small images and fast builds—in theory. In practice, they require some tricks if you want your builds to actually be fast.


  1. Configuring Gunicorn for Docker
    Running in a container isn’t the same as running on a virtual machine or physical server: you need to configure Gunicorn (and other servers) appropriately.

Building production-ready Docker images is tricky…

You want fast builds, small and secure images, operational correctness. And doing it all yourself will take you a week or more of effort.

Want to ship with confidence—in just hours?
Learn the easier way to build production-ready Python containers.