7

I try to integrate the new healthcheck into my docker system, but I don't really know how to do it in the right way :/

The problem is, my database container needs more time to start up and initialize the database then the container who starts my main application. As a result: the main container wont start correct, cause of the missing database connection. I wrote an healthcheck.sh script to check the database container for connectivity, so the main container starts booting after the connectivity is available. But I dont know how to integrate it correctly in the Dockerfile and my docker-compose.yml

healthcheck.sh is like:

#!bin/bash
COUNTER=0
while [[ $COUNTER = 0 ]]; do
  mysql --host=HOST --user="user" --password="password" --database="databasename" --execute="SELECT 1";
  if [[ $? == 1 ]]; then
    sleep 1
    echo "Let's sleep again"
  else
    COUNTER=1
    echo "OK, lets go!"
  fi
done

mysql container Dockerfile:

FROM repository/mysql-5.6:latest
MAINTAINER Me

... some copies, chmod and so on 

VOLUME ["/..."]

EXPOSE 3306

CMD [".../run.sh"]

HEALTHCHECK --interval=1s --timeout=3s CMD ./healthcheck.sh

docker-compose.yml like:

version: '2'
services:
  db:
    image: db image
    restart: always
    dns:
      - 10.
    ports:
      - "${MYSQL_EXTERNAL_PORT}:${MYSQL_INTERNAL_PORT}"
    environment:
      TZ: Europe/Berlin
  data:
    image: data image

  main application:
    image: application image
    restart: always
    dns:
      - 10.
    ports:
      - "${..._EXTERNAL_PORT}:${..._INTERNAL_PORT}"
    environment:
      TZ: Europe/Berlin
    volumes:
      - ${HOST_BACKUP_DIR}:/...
    volumes_from:
      - data
      - db

What do I have to do to integrate this healthcheck into my docker-compose.yml file to work? Or is there any other chance to delay the container startup of my main container?

Thx Markus

aTTraX
  • 81
  • 1
  • 1
  • 5

3 Answers3

7

I believe this is similar to Docker Compose wait for container X before starting Y

Your db_image needs to support curl.
To do that, create your own db_image as:

FROM base_image:latest
RUN apt-get update
RUN apt-get install -y curl 
EXPOSE 3306

Then all you should need is a docker-compose.yml that looks like this:

version: '2'
services:
  db:
    image: db_image
    restart: always
    dns:
      - 10.
    ports:
      - "${MYSQL_EXTERNAL_PORT}:${MYSQL_INTERNAL_PORT}"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:${MYSQL_INTERNAL_PORT}"]
      interval: 30s
      timeout: 10s
      retries: 5
    environment:
      TZ: Europe/Berlin
  main_application:
    image: application_image
    restart: always
    depends_on:
      db:
        condition: service_healthy
    links: 
        - db
    dns:
      - 10.
    ports:
      - "${..._EXTERNAL_PORT}:${..._INTERNAL_PORT}"
    environment:
      TZ: Europe/Berlin
    volumes:
      - ${HOST_BACKUP_DIR}:/...
    volumes_from:
      - data
      - db
David Tobiano
  • 1,188
  • 8
  • 10
5

In general your application should be able to cope with unavailable resources, but there are also some cases when starting up where it is pretty convenient to have one container waiting for another to be "fully available". Docker itself doesn't handle that for you, but there are ways to handle the startup in the resource-using container by delaying the actual command with some script.

There is a good example for a postgresql startup check that can be used in any container that needs to wait for the database to be "fully started". Please see the sample code in the docker docs: https://docs.docker.com/compose/startup-order/

Andreas Jägle
  • 11,632
  • 3
  • 31
  • 31
3

Since docker-compose 1.10.0 you can specify healthchecks in your compose file: https://github.com/docker/docker.github.io/blob/master/compose/compose-file.md#healthcheck

It makes use of https://docs.docker.com/engine/reference/builder/#/healthcheck which has been introducded with Docker 1.12

tomasulo
  • 1,252
  • 8
  • 9
  • 2
    How do you use Docker healthcheck to control startup order of containers? If a container is unhealthy as a result of healthcheck, how can other container read that status and delay its own startup until its dependent container is healthy? – Naymesh Mistry Apr 20 '17 at 04:25