Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker compose wait for database service initialisation

I have a spring boot project which I'd like to containerize using docker. I have a couple of spring boot applications which connect to same MySql server.

My spring applications requires the database to be completely setup (i.e. all the tables to be created and some data to be inserted in some of the tables) in order to start.

I am using Docker version 18.09.0 and docker-compose version 1.23.1 and ubuntu 16.04 LTS


I have two files create.sql and insert.sql, which I use to initialise the database to be used by the application.

I create the images using the command docker-compose.yml and it runs successfully and creates the images.

I have the following questions.

  1. I assume when using docker-compose, a container starts as soon as all its dependent containers have started. Is there a way to wait for the mysql server to be up and ready to accept connections, before my API container gets started?

  2. If I chose to create containers separately for the applications and mysql, and not use docker-compose, how do I make sure that my applications connect to the mysql container?

  3. Is there any other tool which might help me achieve this?

Note: I have tried to use docker inspect <container_id> to find the the IpAddress for the mysql container and use it to connect, but it doesn't work as well.


The following are the files I am using to create images.

docker-compose.yml file.

version: '3'

services:
  demo-mysql:
    image: demo-mysql
    build: ./demo-mysql
    volumes:
      - /mnt/data/mysql-data:/var/lib/mysql
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=demo
      - MYSQL_PASSWORD=root

  demo-api:
    image: demo-api-1.0
    build: ./api
    depends_on:
      - demo-mysql
    ports:
      - 8080:8080
    environment:
      - DATABASE_HOST=demo-mysql
      - DATABASE_USER=root
      - DATABASE_PASSWORD=root
      - DATABASE_NAME=demo
      - DATABASE_PORT=3306

  demo1-app:
    image: demo1-app-1.0
    build: ./demo1
    depends_on:
      - demo-mysql
    ports:
      - 8090:8090
    environment:
      - DATABASE_HOST=demo-mysql
      - DATABASE_USER=root
      - DATABASE_PASSWORD=root
      - DATABASE_NAME=demo
      - DATABASE_PORT=3306

The following is the Dockerfile for the spring boot project

FROM java:8

VOLUME /tmp

ARG DATA_PATH=/src/main/resources
ARG APP_PORT=8080

EXPOSE ${APP_PORT}

ADD /build/libs/demo-api.jar demo-api.jar

ENTRYPOINT ["java","-jar","demo-api.jar"]

The following is the Dockerfile I used to create my mysql image

FROM mysql:5.7

ENV MYSQL_DATABASE=demo \
    MYSQL_USER=root \
    MYSQL_ROOT_PASSWORD=root

ADD ./1.0/create.sql /docker-entrypoint-initdb.d
ADD ./1.0/insert.sql /docker-entrypoint-initdb.d

EXPOSE 3306
like image 860
greenPadawan Avatar asked Nov 21 '18 07:11

greenPadawan


People also ask

What is Depends_on in docker compose?

depends_on is a Docker Compose keyword to set the order in which services must start and stop. For example, suppose we want our web application, which we'll build as a web-app image, to start after our Postgres container.

How do I wait for docker?

Start a container in the background. Run docker wait , which should block until the container exits. In another terminal, stop the first container. The docker wait command above returns the exit code.

Do you need Dockerfiles with docker compose?

Docker compose uses the Dockerfile if you add the build command to your project's docker-compose. yml. Your Docker workflow should be to build a suitable Dockerfile for each image you wish to create, then use compose to assemble the images using the build command.


1 Answers

Use the healthcheck feature of docker-compose (https://docs.docker.com/compose/compose-file/#healthcheck). Something like this:

services:
  demo-mysql:
    image: demo-mysql
    build: ./demo-mysql
    volumes:
      - /mnt/data/mysql-data:/var/lib/mysql
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=demo
      - MYSQL_PASSWORD=root
    healthcheck:
      test: ["CMD-SHELL", 'mysqladmin ping']
      interval: 10s
      timeout: 2s
      retries: 10

The depending containers will not start until the demo-mysql container is healthy

like image 148
Simonluca Landi Avatar answered Nov 09 '22 08:11

Simonluca Landi