0

I have a docker-compose.yml that looks like this:

version: '3.8'
services:
  api:
    container_name: todoapp-api
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 3333:3333
    depends_on:
      postgresdb:
        condition: service_healthy

  postgresdb:
    image: postgres:13
    restart: unless-stopped
    environment:
      - POSTGRES_USER=myuser
      - POSTGRES_PASSWORD=mypassword
      - POSTGRES_DB=mydb
    volumes:
      - postgres:/var/lib/postgresql/data
    ports:
      - '5432:5432'
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready']
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  postgres:

Problem is that I keep getting the error code P1001 when I run this. I figured adding a healthcheck would do the trick but that doesn't work. Plus, depends_on: seems to not be present in v3 above. Is there a way I can write a script for maybe my package.json to wait for the database to be up?

  • Best way is to include retries for database connection in your app. Or any suggestion like wait-for etc. as suggested in [docker docs](https://docs.docker.com/compose/startup-order/) can be used. –  Sep 07 '22 at 14:43

1 Answers1

1

You could waiting for db in the service which needs database itself. To do so, you have to create an entrypoint.sh file & have that run as main command. It would be sth like this:

entrypoint.sh

#!/bin/bash

set -e

# There are some times database is not ready yet!
# We'll check if database is ready and we can connect to it
# then the rest of the code run as well.

echo "Waiting for database..."
echo DB_NAME: ${DB_NAME}
echo DB_HOST: ${DB_HOST}
echo DB_PORT: ${DB_PORT}
while ! nc -z ${DB_HOST} ${DB_PORT}; do sleep 1; done
echo "Connected to database."

# ... Run what you have to here

Dockerfile

...

CMD /usr/app/entrypoint.sh
Sajad Rezvani
  • 366
  • 2
  • 14
  • (For this pattern, I like to end the entrypoint script with `exec "$@"`. In the Dockerfile, make sure you invoke it with JSON-array syntax `ENTRYPOINT ["./entrypoint.sh"]`. That final line will make it run the `CMD`. The big benefit of this is that it's easy to `docker run your-image some-other-command`, which will still get run via the entrypoint wrapper.) – David Maze Sep 07 '22 at 14:50
  • I agree, it's better be run by ENTRYPOINT directive. – Sajad Rezvani Sep 07 '22 at 14:57