If you’re using Docker Compose to orchestrate multiple Docker containers, you may run into instances where you want to delay starting one container until another container finishes doing something (say, database initialization).1
There are some existing tools like docker-wait
for waiting on TCP connections, but if you want to wait on a container that’s building something in a shared volume instead of providing a service, this may not be a great match for what you want to do.
A simple workaround I’ve found for this is to use volumes_from
in docker-compose.yml
and the inotifywait
tool to block execution in one container based on a file semaphore written by another container.
Here’s the directory structure for a minimal example (GitHub repo), where we want to wait until docker-container-2
has finished doing something before starting docker-container-1
:
+-- docker-compose.yml
+-- docker-container-1
| +-- Dockerfile
+-- docker-container-2
+-- Dockerfile
Our docker-compose.yml
looks like this, pulling a volume from container 2 into container 1 with volumes_from
:
Our Dockerfile
for container 2 contains:
And the Dockerfile
for container 1 has:
When we run docker-compose up --force-recreate
in this directory we get the output:
Note that there are some catches to this that you may need to work around, depending on how you plan to use this pattern. For one, it depends on the container being Linux-based and providing inotify
, and inotify-tools
being installed. For another, if you noticed the sleep
command in docker-container-2
, a fast process in one container could race the inotify
watches being set up in another. So if you anticipate that being a potential issue for how you’re using this you’ll need to add some additional logic for it (e.g., only calling inotifywait
if the file semaphore doesn’t already exist). You’ll also notice the tail -f /dev/null
in docker-container-2
to prevent its exit
causing all the other containers in docker-compose to stop (see this related pull request for docker-compose
, which should be in the 1.5 release).
Footnotes
-
See also:
- docker/compose#235: Order of containers starting up?
- docker/compose#374: Is there a way to delay container startup to support dependant services with a longer startup time
- docker/compose#686: Allow dependencies to be specified explicitly with
depends_on
- docker/compose#935: volumes_from not running dependent container(?)