Skip to content

up --wait does not fail when a service becomes unhealthy #1534

Description

@wakairo

Describe the bug

podman-compose up --wait does not fail when a service becomes unhealthy.

When a service uses depends_on with condition: service_healthy, up --wait continues waiting after the dependency has become unhealthy. This wait can also continue beyond --wait-timeout.

Without the dependency, --wait-timeout ends the wait but returns status 0 even though the service remains unhealthy.

Docker Compose reports an error when a required service becomes unhealthy. podman-compose should provide compatible behavior so that CI and scripts neither hang nor report false success.

To Reproduce

Create a directory for the reproducer:

mkdir -p /tmp/podman-compose-unhealthy-repro
cd /tmp/podman-compose-unhealthy-repro

Create compose.yaml:

services:
  dependency:
    image: busybox:latest
    command: ["sh", "-c", "while :; do sleep 3600; done"]
    healthcheck:
      test: ["CMD-SHELL", "exit 1"]
      interval: 1s
      timeout: 1s
      retries: 1

  app:
    image: busybox:latest
    command: ["sh", "-c", "while :; do sleep 3600; done"]
    depends_on:
      dependency:
        condition: service_healthy

The commands below explicitly use unhealthy-repro as the Compose project name:

timeout 10s podman-compose -p unhealthy-repro \
  up -d --wait --wait-timeout 3

printf 'exit status: %s\n' "$?"

Inspect the containers:

podman ps -a \
  --filter label=com.docker.compose.project=unhealthy-repro \
  --format '{{.Names}} {{.Status}}'

Clean up:

podman-compose -p unhealthy-repro down

Expected behavior

As soon as dependency becomes unhealthy:

  • podman-compose up -d --wait should stop waiting.
  • The command should return a non-zero status.
  • app should not be treated as ready.
  • --wait-timeout should bound all readiness waits, including service_healthy dependency waits.

This matches the behavior of Docker Compose.

Actual behavior

The dependency becomes unhealthy, but podman-compose continues waiting.

The external timeout command eventually terminates podman-compose:

exit status: 124

--wait-timeout 3 does not bound this dependency wait.

As a related case, if the app service is removed so that only the unhealthy service remains, this command returns status 0 after the timeout even though the service is still unhealthy:

podman-compose -p unhealthy-repro up -d --wait --wait-timeout 3

Output

$ podman-compose version
podman-compose version 1.6.0

$ podman --version
podman version 4.9.3

Environment:

  • OS: Ubuntu 24.04
  • Podman: 4.9.3, rootless
  • podman-compose: 1.6.0

Additional context

In podman-compose 1.6.0, the readiness code waits for the healthy condition but does not appear to treat unhealthy as a failure:

https://github.com/containers/podman-compose/blob/v1.6.0/podman_compose.py#L3493-L3535

The service_healthy dependency wait also does not appear to be covered by --wait-timeout:

https://github.com/containers/podman-compose/blob/v1.6.0/podman_compose.py#L3685-L3730

Docker Compose explicitly reports an error when a service becomes unhealthy:

https://github.com/docker/compose/blob/main/pkg/compose/convergence.go

A possible fix would be to:

  1. Wait for both healthy and terminal failure states such as unhealthy.
  2. Return a non-zero status immediately when a required service becomes unhealthy.
  3. Apply --wait-timeout to dependency-condition waits as well as the final readiness wait.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions