Your guide to creating production-ready Docker images. | Continue reading
If you’re using a schema management tool like Django ORM or Alembic, you need to run the migration at some point. And it’s tempting to run the migration as part of application startup—when you’re using Docker, for instance, you’ll have an entrypoint that will first run the migrat … | Continue reading
How do you make your application fast? It’s very hard to say in the abstract, because “fast” has no universal meaning—what is slow in one case might be fast is another. And this is a general truth about performance optimization. You need to understand your goals and situation, an … | Continue reading
If you’re building a Docker image, it’s natural to go read Docker’s official documentation’s best practices for Dockerfiles on docs.docker.com. While this document has a lot of excellent and useful information, it also has some problems: important security and performance details … | Continue reading
Writing software for ops is tricky: If you’re a developer, you solve problems by writing software. But if you’re in ops, usually more software means more problems. So if you’re developing software for ops, how can you write software that doesn’t make ops’ life worse? In this arti … | Continue reading
Your Docker build runs too slowly, and it’s annoying—but it’s definitely not an emergency. After all, you’ve got a whole slew of bug fixes and feature requests queued up, and those are more important than your Docker build. So you can never quite justify spending the time to spee … | Continue reading
Can’t connect to the server running in your container? Let’s see why, and how to fix it, starting with an example. Let’s say you run the following command on your computer: $ FLASK_APP=exampleapp:app flask run * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) You can poi … | Continue reading
Researching and then building a production Docker image building setup for your application can take as much as a week, and even more if you’re supporting multiple applications. Or you could do it the fast way. | Continue reading
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. | Continue reading
One important part of running your container in production is locking it down, to reduce the chances of an attacker using it as a starting point to exploit your whole system. Containers are inherently less isolated than virtual machines, and so more effort is needed to secure the … | Continue reading
Building a Docker image often involves installing packages or downloading code, and if you’re installing private code you often need to gain access with a secret: a password, a private key, a token. You don’t want those secrets to end up in the final image, though; if it’s in the … | Continue reading
When it’s time to package up your Python application into a Docker image, the natural thing to do is search the web for some examples. And a quick search will provide you with plenty of simple, easy examples. Unfortunately, these simple, easy examples are often broken in a variet … | Continue reading
Gunicorn is a common WSGI server for Python applications, but most Docker images that use it are badly configured. Running in a container isn’t the same as running on a virtual machine or physical server, and there are also Linux-environment differences to take into account. So t … | Continue reading
Docker builds can be slow, so you want to use Docker’s layer caching, reusing previous builds to speed up the current one. And while this will speed up builds, there’s a down-side as well: caching can lead to insecure images. In this article I’ll cover: Why caching can mean insec … | Continue reading
When you’re building a Docker image for your Python application, you’re building on top of an existing image—and there are many possible choices. There are OS images like Ubuntu and CentOS, and there are the many different variants of the python base image. Which one should you u … | Continue reading
You’ve run your batch process with your scientific model, and after hours and hours it spit out a result. And the result is wrong. You suspect there’s a bug in the calculation, you’re not sure what it is, and the slow feedback cycle is making debugging even harder. Wouldn’t it be … | Continue reading
The more you use JSON, the more likely you are to encounter JSON encoding or decoding as a bottleneck. Python’s built-in library isn’t bad, but there are multiple faster JSON libraries available: how do you choose which one to use? Unfortunately, I can’t just tell you which libra … | Continue reading
Your test suite runs too slowly, and it’s annoying—but it’s definitely not an emergency. After all, you’ve got a whole slew of bug fixes and feature requests queued up, and those are more important than your test suite. So you can never quite justify spending the time to speed it … | Continue reading
Your Python code needs some compilation, and you’ve learned that multi-stage builds are the way to get smaller Docker images. But how exactly do multi-stage images work, in general and for Python? How should you implement them in practice? In this article you’ll learn: The basics … | Continue reading
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! Bigger images mean slower deploys, slower test runs, potentially highe … | Continue reading
When you’re packaging your Python application in a Docker image, you’ll often use a virtualenv. (There are cases where it’s unnecessary, but that is a different discussion.) Since you’re using a virtualenv, you need to activate it—but if you’re just getting started with Dockerfil … | Continue reading
You’re running you test suite or your Docker image packaging on a EC2 server. And it’s slow. docker pull takes 15 minutes just to verify the images it downloaded in 1 minute. apt or dnf installs take another 15 minutes. pip install or conda install take even more time. It’s a fas … | Continue reading
You submit a pull request, the CI system kicks off the tests—and then you wait. And wait some more. And by the time it turns red to tell you there’s a problem you’ve moved on to something else. What were you doing again? And eventually, hours or even days later, you finally get y … | Continue reading