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:
--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:
- Wait for both
healthy and terminal failure states such as unhealthy.
- Return a non-zero status immediately when a required service becomes unhealthy.
- Apply
--wait-timeout to dependency-condition waits as well as the final readiness wait.
Describe the bug
podman-compose up --waitdoes not fail when a service becomes unhealthy.When a service uses
depends_onwithcondition: service_healthy,up --waitcontinues waiting after the dependency has become unhealthy. This wait can also continue beyond--wait-timeout.Without the dependency,
--wait-timeoutends the wait but returns status0even though the service remains unhealthy.Docker Compose reports an error when a required service becomes unhealthy.
podman-composeshould 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-reproCreate
compose.yaml:The commands below explicitly use
unhealthy-reproas the Compose project name:Inspect the containers:
podman ps -a \ --filter label=com.docker.compose.project=unhealthy-repro \ --format '{{.Names}} {{.Status}}'Clean up:
Expected behavior
As soon as
dependencybecomes unhealthy:podman-compose up -d --waitshould stop waiting.appshould not be treated as ready.--wait-timeoutshould bound all readiness waits, includingservice_healthydependency waits.This matches the behavior of Docker Compose.
Actual behavior
The dependency becomes unhealthy, but
podman-composecontinues waiting.The external
timeoutcommand eventually terminatespodman-compose:--wait-timeout 3does not bound this dependency wait.As a related case, if the
appservice is removed so that only the unhealthy service remains, this command returns status0after the timeout even though the service is still unhealthy:Output
Environment:
Additional context
In podman-compose 1.6.0, the readiness code waits for the
healthycondition but does not appear to treatunhealthyas a failure:https://github.com/containers/podman-compose/blob/v1.6.0/podman_compose.py#L3493-L3535
The
service_healthydependency 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:
healthyand terminal failure states such asunhealthy.--wait-timeoutto dependency-condition waits as well as the final readiness wait.