Good old bash for startup dependency management
Good old bash for startup dependency management
January 16, 2018
I wanted to share a really simple and clean way to wait for dependencies to be available in Unix*y environments. I often use this script to orchestrate my docker containers.
For example, if I want to bring up a cluster of containers that all work together and then once they are all working, do something else, like run some tests, this script comes in super handy.
Here is a typical setup that this helps with:
Service depends on:
- Redis
- Mysql
- Mongodb
Expected startup sequence:
- Start Redis, Mysql, Mongodb containers
- Wait for the containers to start running
- Wait for each of the processes inside the containers to get ready
- For example, wait till Mysql is actually ready to accept connections
- Finally, run the
Service
#!/bin/bash
######################################################################
# Waits for Mongodb, Redis and Mysql to be ready
# usage examples:
# wait-for-dependencies.sh echo "READY TO GO"
# wait-for-dependencies.sh make build
# Exit Codes: 0 for success, 2 if wait command timed out
######################################################################
TIME_LIMIT=15
INTERVAL=2
set -e
POST_RUN_CMD=( "$@" )
wait_for_command() {
SECONDS=0
DEP_NAME="${1}"
CMD="${2}"
until ${CMD} &> /dev/null; do
>&2 echo "${DEP_NAME} is unavailable - sleeping. Time elapsed: ${SECONDS}"
sleep $INTERVAL
if [ "${SECONDS}" -gt "${TIME_LIMIT}" ]; then
>&2 echo "TIMEOUT: ${DEP_NAME} failed to come up"
exit 2
fi
done
>&2 echo "${DEP_NAME} is ready"
}
# WAIT FOR MONGO
MONGO_NAME='mongodb'
MONGO_WAIT_CMD='mongo --eval "db.stats()" --host mongo'
# WAIT FOR MYSQL
MYSQL_NAME='mysql'
MYSQL_WAIT_CMD='mysqladmin ping --protocol tcp --host mysql --user root'
# WAIT FOR REDIS
REDIS_NAME='redis'
REDIS_WAIT_CMD='redis-cli ping'
wait_for_command "${MONGO_NAME}" "${MONGO_WAIT_CMD}"
wait_for_command "${MYSQL_NAME}" "${MYSQL_WAIT_CMD}"
wait_for_command "${REDIS_NAME}" "${REDIS_WAIT_CMD}"
# Finally, run the arbitrary command after this wait it done.
exec "${POST_RUN_CMD[@]}"
Last updated on