Originally Published: 2015-09-24
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
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-compose.yml +-- docker-container-1 | +-- Dockerfile +-- docker-container-2 +-- Dockerfile
docker-compose.yml looks like this, pulling a volume from container 2 into container 1 with
Dockerfile for container 2 contains:
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-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).
- 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
- docker/compose#935: volumes_from not running dependent container(?)