Docker Tip #90: Docker Compose Up Is Faster than Stop + Up

Docker Compose up by itself is smart enough to only recreate containers that need to change based on a new image or env variable.
This has been something I’ve done for years but only now realized I never wrote about it. This tip mainly applies to using Docker Compose in production on a single server.
Prefer video? Here’s a recorded version of this tip on YouTube that shows a demo of what’s written below.
Let’s say you have a typical web app in Docker Compose with web
, worker
, db
and cache
services. All of these are defined as separate services in a single docker-compose.yml
file such as what you might see in my example apps for Flask, Rails and Django.
If you run docker-compose up -d
you can start everything up initially like usual but now let’s say you change an environment variable or pull / build a new image for your web
or worker
.
If you run docker-compose up -d
again Docker Compose will automatically recreate just the web
and worker
containers or more generally only what changed. Everything else will remain untouched and running as seen below:
helloflask_postgres_1 is up-to-date
helloflask_redis_1 is up-to-date
Recreating helloflask_web_1 ... done
Recreating helloflask_worker_1 ... done
In the grand scheme of things this could mean being able to fully restart your web app with 3 seconds of downtime instead of 6. That might not seem like a lot but it’s substantial for single server deploys. You’re cutting your downtime in half!
Even in cases where every container needs to be recreated doing docker-compos up -d
is faster. I noticed on some projects that it takes about 4 seconds to recreate everything with docker-compose up -d
but ~8 seconds if I do a docker-compose stop && docker-compose up -d
.
It will also send a SIGTERM
so it’s not like it’s cheating by doing a SIGKILL
. You can see what happens during the recreate process by running docker events
beforehand and checking which Docker API calls are made. It will perform a kill
command but with a signal=15
which is a SIGTERM
so your containers can gracefully stop.
That means in your deploy scripts you can typically do docker-compose pull && docker-compose up -d
instead of docker-compose pull && docker-compose stop && docker-compose up -d
.