Use a tool such as wait-for-it, dockerize, or sh-compatible wait-for. These are small wrapper scripts which you can include in your application’s image to poll a given host and port until it’s accepting TCP connections.
For example, to use wait-for-it.sh or wait-for to wrap your service’s command:
version: "2"
services:
web:
build: .
ports:
- "80:8000"
depends_on:
- "db"
command: ["./wait-for-it.sh", "db:5432", "--", "python", "app.py"]
db:
image: postgres
Tip: There are limitations to this first solution. For example, it doesn’t verify when a specific service is really ready. If you add more arguments to the command, use the bash shift command with a loop, as shown in the next example.
Alternatively, write your own wrapper script to perform a more application-specific health check. For example, you might want to wait until Postgres is definitely ready to accept commands:
#!/bin/bash
# wait-for-postgres.sh
set -e
host="$1"
shift
cmd="$@"
until psql -h "$host" -U "postgres" -c '\q'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up - executing command"
exec $cmd
You can use this as a wrapper script as in the previous example, by setting:
command: ["./wait-for-postgres.sh", "db", "python", "app.py"]