-
-
Save nicerobot/1136dcfba6ce3da67ce3ded5101a4078 to your computer and use it in GitHub Desktop.
#!/bin/bash -e | |
# wait-for-postgres.sh | |
# Adapted from https://docs.docker.com/compose/startup-order/ | |
# Expects the necessary PG* variables. | |
until psql -c '\l'; do | |
echo >&2 "$(date +%Y%m%dt%H%M%S) Postgres is unavailable - sleeping" | |
sleep 1 | |
done | |
echo >&2 "$(date +%Y%m%dt%H%M%S) Postgres is up - executing command" | |
exec ${@} |
"Better" is subjective. It's more versatile maybe. That doesn't always mean better ;-) Simplicity also matters and I didn't need a retry limit.
Also, I wouldn't provide the --dbname
flag. psql
supports PG*
environment variables. Let the caller provide them in the way psql
already expects.
I would also adhere to a different Bash style.
So if you want retries and want a truly better variant, I would write it like this:
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
retry() {
local max_attempts="${1}"; shift
local retry_delay_seconds="${1}"; shift
local cmd="${@}"
local attempt_num=1
until ${cmd}; do
(( attempt_num >= max_attempts )) && {
echo "Attempt ${attempt_num} failed and there are no more attempts left!"
return 1
}
echo "Attempt ${attempt_num} failed! Trying again in ${retry_delay_seconds} seconds..."
attempt_num=$[ attempt_num + 1 ]
sleep ${retry_delay_seconds}
done
}
retry 1>&2 ${MAX_ATTEMPTS:-5} ${RETRY_DELAY_SECONDS:-1} psql -c '\l'
psql "${@}"
This example (as the original one in the docker website) is using the psql command. This command is not available in the "webapp" service though (only available in the "db" service). Am I getting something wrong?
You will need to install the "postgresql-client" package for these commands to be available in the webapp.
The included pg_isready
command achieves the same as above without the retry limit.
See the complete config using this technique here.
A simplified Dockerfile is shown below. You will need to include a pgsql
link for hostname in docker-compose.yml.
FROM openjdk:11
RUN apt-get update && apt-get install -y procps curl net-tools telnet
RUN apt-get install -y postgresql-client
#other things
COPY build/libs/app-0.0.1.war app.war
EXPOSE 8080
CMD until pg_isready --host=pgsql; do sleep 1; done \
&& java -jar app.war
For the above script replace the CMD with :
CMD wait-for-postgres.sh && java -jar app.war
here's better variant