Skip to content

Instantly share code, notes, and snippets.

@rochacbruno
Last active February 16, 2022 18:00
Show Gist options
  • Star 46 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save rochacbruno/bdcad83367593fd52005 to your computer and use it in GitHub Desktop.
Save rochacbruno/bdcad83367593fd52005 to your computer and use it in GitHub Desktop.
Docker-compose wait-to-start

When unsing docker compose you can have a problem with the order of dependent linked containers

The solution is to start a script which tries to access a service and waits until it gets ready before loading your program

# This code needs to access elastic search!
from datetime import datetime
from elasticsearch import Elasticsearch
es = Elasticsearch('elastic')
es.index(index="my-index", doc_type="test-type", id=42, body={"any": "data", "timestamp": datetime.now()})
print es.get(index="my-index", doc_type="test-type", id=42)
elastic:
image: elasticsearch
command: elasticsearch -Des.node.name="YourNodeName"
ports:
- "9200:9200"
app:
image: ubuntu:14.04
command: sh wait_to_start.sh
working_dir: /src
links:
- elastic:elastic
volumes:
- .:/src
environment:
- WAIT_COMMAND=[ $(curl --write-out %{http_code} --silent --output /dev/null http://elastic:9200/_cat/health?h=st) = 200 ]
- WAIT_START_CMD=python access_elastic_search.py
- WAIT_SLEEP=2
- WAIT_LOOPS=10
#!/bin/bash
echo $WAIT_COMMAND
echo $WAIT_START_CMD
is_ready() {
eval "$WAIT_COMMAND"
}
# wait until is ready
i=0
while ! is_ready; do
i=`expr $i + 1`
if [ $i -ge $WAIT_LOOPS ]; then
echo "$(date) - still not ready, giving up"
exit 1
fi
echo "$(date) - waiting to be ready"
sleep $WAIT_SLEEP
done
#start the script
exec $WAIT_START_CMD
@dandavison
Copy link

Just thought I'd mention that you might be able to make this shorter by using timeout and until, something like:

timeout $WAIT_TIMEOUT bash -c "until $WAIT_COMMAND; do sleep $WAIT_SLEEP; done"

@jwo
Copy link

jwo commented May 22, 2018

If you come across an error "Invalid interpolation format for "environment" option in service", you need to escape the $

environment:
  - WAIT_COMMAND=[ $$(curl --write-out %{http_code} --silent --output /dev/null http://elastic:9200/_cat/health?h=st) = 200 ]

@jeroenvermeulen
Copy link

jeroenvermeulen commented Sep 26, 2020

Inspired by the above I have created this oneliner:

ESHOST="elastic"
timeout 300 bash -c "until curl --silent --output /dev/null http://$ESHOST:9200/_cat/health?h=st; do printf '.'; sleep 5; done; printf '\n'"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment