In docker-compose a common problem is starting services and daemons in containers that depends on services running on linked containers, in example: your app depends on elasticsearch but it is not ready when the app container is started. Solution is to use a wait script.
I knew that docker-compose team is working on adding a WAIT parameter, but while it is not ready we can use a wait script to load our services.
The process is simple, your container will execute a shell script that will try to execute a HEALTH CHECK many times you want before starting the main command. The health check, the command, the sleep and how many loops to try will be defined in environment variables
This is a program that needs to access an elasticsearch server located in 'elastic' host (that will be mapped by compose
access_elastic_search.py
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)
docker-compose.yml
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
wait_to_start.sh
magic
#!/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
Now when you start your environment with docker-compose up
the app container will start and execute wait_to_start.sh
script, which will perform the test defined in WAIT_COMMAND
environment variable and will retry until the test succeeds, so it will end executing the program defined in WAIT_START_CMD
Full code on gist: https://gist.github.com/rochacbruno/bdcad83367593fd52005
This code was made with StackOverflow help