2

I'm trying to start 3 docker containers in a sequential order using the docker-compose. I have the following containers:

  • app-service-db container -> Database
  • config-service container -> Spring boot application
  • app-service container -> Spring boot application

I want the ' app-service ' container to start only when the other two containers have finish starting. I'm using the ' wait-for ' script to wait for the services to become available (https://github.com/Eficode/wait-for).

Here is what I have inside the docker-compose.yml

    version: '3.4'
services:
    config-service:
      image: "config-service:1.0"
      hostname: config-service
      container_name: config-service
      build:
        context: ../config
        dockerfile: config.dockerfile
      expose:
        - "8888"
      logging:
        driver: json-file
    app-service-db:
      image: "app-service-db:10.3"
      hostname: app-service-db
      container_name: app-service-db
      build:
        context: ../app-service
        dockerfile: app-db.dockerfile
      environment:
        MYSQL_ROOT_PASSWORD: password
        MYSQL_DATABASE: app
      expose:
        - "3306"
      logging:
        driver: json-file  
    app-service:
        image: "app-service:1.0"
        hostname: app-service
        container_name: app-service
        build:
          context: ../app-service
          dockerfile: app.dockerfile
        ports:
          - "8080:8080"
        expose:
          - "8080"
        logging:
          driver: json-file
        command: sh -c './wait-for app-service-db:3306 && config-service:8888'  
        depends_on:
          - config-service
          - app-service-db

config.dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD target/config-1.0-final.jar config.jar
ENTRYPOINT ["java", "-jar", "config.jar"]
EXPOSE 8888

app-db.dockerfile

FROM mariadb:10.3

app.dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD target/app-1.0-final.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
EXPOSE 8080

When I run the ' docker-compose up ' cmd the ' app-service ' container is starting before the ' app-service-db ' and ' config-service ' have finished and is exited because it can't find any connection. How can I make this work and force the ' app-service ' container to start only when the other two containers have started.

Thanks in advance.

Bad_Pan
  • 488
  • 13
  • 20

2 Answers2

2

I see more problems in your configs. There is problem with entrypoint and command relation, to fully uderstand that please see this What is the difference between CMD and ENTRYPOINT in a Dockerfile? So your entrypoint is to run java application - that's probably why wait is not working. I would suggest to override entrypoint for app-service by adding following section in docker-compose:

entrypoint: sh -c './wait-for app-service-db:3306 && ./wait-for config-service:8888 && java -jar app.jar'

Also I can't see where you are adding this script wait-for into docker image (missing ADD in app's dockerfile?)

Jakub Bujny
  • 4,400
  • 13
  • 27
  • That was it....I was missing the ' ADD ./wait-for wait-for ' in the docker image and also I removed the ENTRYPOINT...THANKS for the help – Bad_Pan Nov 23 '17 at 07:12
1

You can ensure the start ordering of your services defined in your docker-compose.yml with the depends_on keyword: https://docs.docker.com/compose/compose-file/#depends_on

This is a Docker runtime thing. You don't specify this in a Dockerfile, from which you build your Docker image.

Docker does not wait for your config and db services to finish starting, before starting your service. But Docker has a article in the official documentation explaining two alternatives to solve this use-case: https://docs.docker.com/compose/startup-order/

  1. Use tools as wait-for-it (https://github.com/vishnubob/wait-for-it) or dockerize (https://github.com/jwilder/dockerize)
  2. or write your own wait script

In the article https://docs.docker.com/compose/startup-order/ are examples for both solutions.

Simon Schürg
  • 2,134
  • 2
  • 20
  • 31