dockerdocker-compose

How to wait for mysql docker-entrypoint-initdb before starting a service


I have a dockerized app that uses mysql, express & react.

I need to first initialize mysql with a docker-entrypoint-initdb.d before starting the express app. However, when mysql server starts it doesn't execute the starting .sql script right away and my_database_name starts initially empty.

In that timegap, my express app starts and tries to query en empty database. Later the initialization script works as intended and fills my_database_name which is already too late by then since my express app has already started.

I've tried depends_on/condition as shown below but Version 3 no longer supports the condition form of depends_on as stated in the docs.

version: '3.8'

services:
  api-server:
    build:
      context: ./server
      dockerfile: ./Dockerfile
    image: myapp_server
    env_file: ./server/.env
    stdin_open: true
    tty: true
    depends_on:
      mysqldb:
        condition: service_healthy
    ports:
      - 9000:9000
    networks:
      - mysern-app
    container_name: my_express_app

  mysqldb:
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: my_database_name
    volumes:
      - mysql-data:/data/db
      - ./db/backup/:/mysql/backup
      - ./db/init:/docker-entrypoint-initdb.d
    healthcheck:
      test: 'not sure what to write in here as well'
      interval: 1s
      retries: 120
    networks:
      - mysern-app
    ports:
      - 3306:3306
    container_name: my_mysql_app
networks:
  mysern-app:
    driver: bridge
volumes:
  mysql-data:
    driver: local

I ultimately want to do this sequence:

Start mysqldb > fill the table from the script > start the express app


Solution

  • There are several things you can do:

    1. Add restart: always to your api-server. If it crashes because MySQL is not yet available - it will restart until MySQL will be available. I'm assuming that your api-server will crash if MySQL is not available.
    2. In case it won't crash, implement health-check for your service, so it won't be available if MySQL isn't available.

    docker-compose is your orchestrator and it can help you and take care of failures. In real-world, your MySQL might be not available for a second too, and you must know how to handle that.