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. This applies to .env
changes too. 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
.