2

I am trying to run my app which depends_on my Postgresql in Docker let say my database PostgreSQL not running now

and in my docker-compose.yml:

version: "3" services: myapp: depends_on: - db container_name: myapp build: context: . dockerfile: Dockerfile restart: on-failure ports: - "8100:8100" db: container_name: postgres restart: on-failure image: postgres:10-alpine ports: - "5555:5432" environment: POSTGRES_USER: myuser POSTGRES_PASSWORD: 12345678 POSTGRES_DB: dev 

when I try docker-compose up -d yes it created the postgres and then create that myapp service but it seems my Postgresql is not running yet, after finish install and running myapp, it said:

my database server not running yet

how to make myapp running until that db service know that my db running ??

0

2 Answers 2

2

The documentation of depends_on says that:

depends_on does not wait for db to be “ready” before starting myapp - only until it have been started.

So you'll have to check that your database is ready by yourself before running your app.

Docker has a documentation that explains how to write a wrapper script to do that:

#!/bin/sh # wait-for-postgres.sh set -e host="$1" shift cmd="$@" until PGPASSWORD=$POSTGRES_PASSWORD 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 

Then you can just call this script before running your app in your docker-compose file:

command: ["./wait-for-postgres.sh", "db", "python", "app.py"] 

There are also tools such as wait-for-it, dockerize or wait-for.


However these solutions has some limitations and Docker says that:

The best solution is to perform this check in your application code, both at startup and whenever a connection is lost for any reason.

This method will be more resilient.

Here is how I use a retry strategy in javascript:

 async ensureConnection () { let retries = 5 const interval = 1000 while (retries) { try { await this.utils.raw('SELECT \'ensure connection\';') break } catch (err) { console.error(err) retries-- console.info(`retries left: ${retries}, interval: ${interval} ms`) if (retries === 0) { throw err } await new Promise(resolve => setTimeout(resolve, interval)) } } } 
Sign up to request clarification or add additional context in comments.

7 Comments

what the mean command "db" in you said above? i am tring to understand , let say i have username=foo and password=bar and db_name=prod with port=555 and host=local, how can i use it in that script??
@mickael-b - you edited your answer to include all that I've wrote, so would thoughtful to refer to that.
db is the hostname of the container. you can provide flags to the psql command: the host using -h, the port -p, the database -d the username -U and the password you can use the PGPASSWORD environment variable.
@certual - you need to add a POSTGRES_PASSWORD to your environment variables with value "bar", in the script that @mickael-b posted replace -U postgres with -U foo and put your port in the script like this: command: ["./wait-for-postgres.sh", "url-to-your-db/prod:5555", "python", "app.py"]
@Ultcyber Hi, I didn't saw your answer I've quoted the official documentation. Also you might want to extract the essential information from your link. See How to Answer and meta.stackexchange.com/questions/7656/…
|
0

Please have a look at: https://docs.docker.com/compose/startup-order/.

Docker-compose won't wait for your database, you need a way to check it externally (via script or retrying the connection as Mickael B. proposed). One of the solutions proposed in the above link is a wait-for.sh utility script - we used it in a project and it worked quite well.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.