act-studio
act-studio

Reputation: 61

Docker - How to wait for container running

i want launch three containers for my web application. The containers are: frontend, backend and mongo database.
To do this i write the following docker-compose.yml

version: '3.7'

services:
  web:
    image: node
    container_name: web
    ports:
    - "3000:3000"
    working_dir: /node/client
    volumes:
    - ./client:/node/client
    links:
    - api
    depends_on:
    - api
    command: npm start
  api:
    image: node
    container_name: api
    ports:
    - "3001:3001"
    working_dir: /node/api
    volumes:
    - ./server:/node/api
    links:
    - mongodb
    depends_on:
    - mongodb
    command: npm start
  mongodb:
    restart: always
    image: mongo
    container_name: mongodb
    ports:
    - "27017:27017"
    volumes:
    - ./database/data:/data/db
    - ./database/config:/data/configdb

and update connection string on my .env file

MONGO_URI = 'mongodb://mongodb:27017/test'

I run it with docker-compose up -d and all go on.
The problem is when i run docker logs api -f for monitoring the backend status: i have MongoNetworkError: failed to connect to server [mongodb:27017] on first connect error, because my mongodb container is up but not in waiting connections (he goes up after backend try to connect).

How can i check if mongodb is in waiting connections status before run api container?

Thanks in advance

Upvotes: 1

Views: 2046

Answers (1)

BMitch
BMitch

Reputation: 264346

Several possible solutions in order of preference:

  1. Configure your application to retry after a short delay and eventually timeout after too many connection failures. This is an ideal solution for portability and can also be used to handle the database restarting after your application is already running and connected.

  2. Use an entrypoint that waits for mongo to become available. You can attempt a full mongo client connect + login, or a simple tcp port check with a script like wait-for-it. Once that check finishes (or times out and fails) you can continue the entrypoint to launching your application.

  3. Configure docker to retry starting your application with a restart policy, or deploy it with orchestration that automatically recovers when the application crashes. This is a less than ideal solution, but extremely easy to implement.

Here's an example of option 3:

  api:
    image: node
    deploy:
      restart_policy:
        condition: unless-stopped

Note, looking at your compose file, you have a mix of v2 and v3 syntax in your compose file, and many options like depends_on, links, and container_name, are not valid with swarm mode. You are also defining settings like working_dir, which should really be done in your Dockerfile instead.

Upvotes: 1

Related Questions