Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker healthcheck in composer file

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

like image 404
aTTraX Avatar asked Aug 11 '16 11:08

aTTraX


Video Answer


2 Answers

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
like image 85
David Tobiano Avatar answered Sep 19 '22 05:09

David Tobiano


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/

like image 28
Andreas Jägle Avatar answered Sep 18 '22 05:09

Andreas Jägle