dockerdocker-composeyamlfailover

Docker compose not respecting depends_on when target container is stoped/down


I have my docker-compose.yml like:

version: '3.9'
services:

    app:
        image: whatever:latest
        ports:
            - "8081:8080"
        healthcheck:
            test: "curl -s http://localhost:8080/q/health | grep -q '\"status\": \"UP\"'"
            interval: 5s
            timeout: 5s
            retries: 20

    app-monitor:
        image: whatever:latest
        depends_on:
            app:
                condition: service_healthy

This works very well on docker-compose up -d . But there's a problem, steps to reproduce:

  1. docker-compose up -d
  2. docker-compose stop app
  3. docker-compose start app-monitor (Starting app-monitor ... done)

Shoudn't step 3 fail? How do I make service app-monitor to fail if the depends_on target service is down?

My purpose here is to make sure all docker-compose services are up and running at all times, in bash would look like:

if ! docker-compose start app-monitor &> /dev/null; then
    docker-compose down && docker-compose up -d
fi

Solution

  • docker-compose stop leaves a container in an unusual state, where the container exists but its process isn't running. In turn docker-compose start is only useful with containers in this unusual state. Since it's not creating new containers, start doesn't check depends_on: constraints; its assumed that these constraints were already met when the container was created at docker-compose up time.

    In practice I'd almost never use either docker-compose stop or start. (Compare to managing non-container server process with kill -STOP and kill -CONT, rather than asking your init system to stop or restart the service.)

    In normal operation I'd usually depend on docker-compose up -d to do the right thing. You shouldn't manually need to start or stop containers, just run up. If a container isn't in the state described in the docker-compose.yml file then Compose will make it so, possibly deleting and recreating the container if necessary.

    # make sure all services are up and running
    docker-compose up -d  # no explicit `docker-compose start` or `down`
    
    # update images if necessary
    docker-compose pull && docker-compose up -d
    
    # restart the app-monitor
    docker-compose up -d --force-recreate app-monitor