13

I have the following compose file:

version: "3"

services:

  zookeeper:
    image: docker-dev.art.intern/wurstmeister/zookeeper:latest
    ports:
      - 2181:2181

  kafka:
    image: docker-dev.art.intern/wurstmeister/kafka:latest
    ports:
      - 9092:9092
    environment:
      - KAFKA_LISTENERS=PLAINTEXT://:9092
      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092
      - KAFKA_ADVERTISED_HOST_NAME=kafka
      - KAFKA_ADVERTISED_PORT=9092
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
    depends_on:
      - zookeeper

  app:
    build:
      context: ./
      dockerfile: app/Dockerfile
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:4020/actuator/health"]
      interval: 30s
      timeout: 10s
      retries: 5
    depends_on:
      - kafka
      - zookeeper

  app-test:
    build:
      context: ./
      dockerfile: test/Dockerfile
    depends_on:
      app:
        condition: service_healthy

As you can see im implementing a healthcheck for the app and I use service_healthy condition. But that leads to the error:

The Compose file '.\docker-compose.yml' is invalid because:
services.app-test.depends_on contains an invalid type, it should be an array

Is there a way to fix that issue?

If I change to array sanytax:

...

  app-test:
    build:
      context: ./
      dockerfile: test/Dockerfile
    depends_on:
      - app:
          condition: service_healthy

The error changes to:

The Compose file '.\docker-compose.yml' is invalid because:
services.app-test.depends_on contains an invalid type, it should be a string
Mulgard
  • 9,877
  • 34
  • 129
  • 232

3 Answers3

14

This appears to have been removed in version 3 of the docker compose specification, but then re-introduced in version 3.9.

See https://github.com/compose-spec/compose-spec/blob/master/spec.md#long-syntax-1

Note that this seems to require Compose V2, which is executed as docker compose on the latest docker binary.

See https://docs.docker.com/compose/#compose-v2-and-the-new-docker-compose-command

Kevin Campbell
  • 629
  • 7
  • 5
7

you can do that with a compose file version 2.1, but it was removed in compose file version 3.

There are several things to be aware of when using depends_on:

  • depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started. If you need to wait for a service to be ready, see Controlling startup order for more on this problem and strategies for solving it.

yet, will advise you not to downgrade your compose file. but rather handle it appropriately with a wrapper script.

you might find wait-for-it, dockerize, and/or wait-for handy.

in compose version 3 you can use depends long syntax to specify a condition

condition: condition under which dependency is considered satisfied

  • service_started: is an equivalent of the short syntax described above
  • service_healthy: specifies that a dependency is expected to be “healthy” (as indicated by healthcheck) before starting a dependent service.
  • service_completed_successfully: specifies that a dependency is expected to run to successful completion before starting a dependent service.

e.g.

services:
  web:
    build: .
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
  redis:
    image: redis
  db:
    image: postgres
Mr.
  • 9,429
  • 13
  • 58
  • 82
  • With compose 3.4 you get healthchecks, apparently with which you can add custom code for checks. I am not sure these wait scripts are useful anymore. – ᐅdevrimbaris Jan 09 '23 at 21:17
-3

Edit: this only solves the YAML error, and still doesn't produce a working docker-compose since depends_on is not valid in Compose version 3. You need either Compose version 2.1 or the Compose Specification.


You're missing a - to make depends_on an array:

  app-test:
    build:
      context: ./
      dockerfile: test/Dockerfile
    depends_on:
      - app:
          condition: service_healthy

Notice the - before app. Without it, services.app-test.depends_on will be an object, not an array. Also pay attention to the amount of spaces: if condition is in the same column as app, you will also get an undesired result.

When decoding your YAML, this is what you get (in JSON):

{
  "app-test": {
    "build": {
      "context": "./",
      "dockerfile": "test/Dockerfile"
    },
    "depends_on": {
      "app": {
        "condition": "service_healthy"
      }
    }
  }
}

With the added -:

{
  "app-test": {
    "build": {
      "context": "./",
      "dockerfile": "test/Dockerfile"
    },
    "depends_on": [
      {
        "app": {
          "condition": "service_healthy"
        }
      }
    ]
  }
}
Leonardo Dagnino
  • 2,914
  • 7
  • 28
  • If I do like you say the error changes to: `The Compose file '.\docker-compose.yml' is invalid because: services.app-test.depends_on contains an invalid type, it should be a string` – Mulgard Feb 10 '22 at 05:23
  • Seems like doing `- app:` is not allowed. With array notation it must be `- app` without ":". And with that you cant provide the condition. – Mulgard Feb 10 '22 at 05:31
  • From a quick look at the [Compose file version 3 reference](https://docs.docker.com/compose/compose-file/compose-file-v3/#depends_on), it seems `condition:` inside `depends_on:` is not supported anymore - it was only in [version 2](https://docs.docker.com/compose/compose-file/compose-file-v2/#depends_on). – Leonardo Dagnino Feb 10 '22 at 05:35
  • Also, compose v2 doesn't need the `-`, since `depends_on` is not an array in v2 – Leonardo Dagnino Feb 10 '22 at 05:37
  • With version 2 I get the exact same error. And if v3 does not support it anymore, how are we supposed to handle this now, if one service depends on the startup of another service. – Mulgard Feb 10 '22 at 05:38
  • I don't think it's the exact same error, it's probably a bit different. More specifically, you need the 2.1 version, as described in the documentation. I'm not very up to date with `docker compose`, but it seems now there is also an unified [compose specification](https://github.com/compose-spec/compose-spec/blob/master/spec.md) which supports `condition` again. You might also want to use a wrapper script to wait for other services to be up. – Leonardo Dagnino Feb 10 '22 at 05:43
  • For more details, you can see [this question](https://stackoverflow.com/questions/47710767/what-is-the-alternative-to-condition-form-of-depends-on-in-docker-compose-versio), which talks both about alternatives and about the unified compose spec. – Leonardo Dagnino Feb 10 '22 at 05:45