Describe the bug
podman-compose accepts the Compose Specification field
healthcheck.start_interval, but it does not cause health checks to run at
that interval during healthcheck.start_period.
The current implementation maps:
healthcheck:
start_interval: 1s
to:
--health-startup-interval 1s
Source:
|
# interval, timeout, start_period, and start_interval are specified as durations. |
|
if "interval" in healthcheck: |
|
podman_args.extend(["--health-interval", healthcheck["interval"]]) |
|
if "timeout" in healthcheck: |
|
podman_args.extend(["--health-timeout", healthcheck["timeout"]]) |
|
if "start_period" in healthcheck: |
|
podman_args.extend(["--health-start-period", healthcheck["start_period"]]) |
|
if "start_interval" in healthcheck: |
|
podman_args.extend(["--health-startup-interval", healthcheck["start_interval"]]) |
However, Podman's --health-startup-interval belongs to Podman's separate
startup-healthcheck mechanism.
That mechanism is gated by --health-startup-cmd.
podman-compose generates --health-cmd, but does
not generate --health-startup-cmd, so the startup interval does not create
or affect a startup healthcheck.
More importantly, the two settings have different semantics:
- Compose
start_interval changes the interval of the regular healthcheck
during start_period.
- Podman
--health-startup-interval controls a separate startup healthcheck,
which stops after its configured success condition is met.
- Podman's startup healthcheck is not bounded by
--health-start-period.
Therefore, mapping start_interval to --health-startup-interval is not
equivalent to the Compose Specification, even if an
--health-startup-cmd were also generated.
This mapping was introduced as support for start_interval in #1271. The
current unit test verifies the generated CLI argument, but does not verify
the resulting healthcheck schedule:
|
async def test_healthcheck_options(self) -> None: |
|
c = create_compose_mock() |
|
cnt = get_minimal_container() |
|
cnt["healthcheck"] = { |
|
"test": ["CMD", "cmd", "arg1", "arg2"], |
|
"interval": "1m", |
|
"timeout": "10s", |
|
"retries": "3", |
|
"start_period": "5s", |
|
"start_interval": "6s", |
|
} |
|
|
|
args = await container_to_args(c, cnt) |
|
self.assertEqual( |
|
args, |
|
[ |
|
"--name=project_name_service_name1", |
|
"-d", |
|
"--network=bridge:alias=service_name", |
|
"--health-cmd", |
|
'["cmd", "arg1", "arg2"]', |
|
'--health-interval', |
|
'1m', |
|
'--health-timeout', |
|
'10s', |
|
'--health-start-period', |
|
'5s', |
|
'--health-startup-interval', |
|
'6s', |
|
'--health-retries', |
|
'3', |
|
"busybox", |
|
], |
This is partly related to a missing Podman runtime feature, but the
podman-compose-specific bug is that it accepts the Compose field and
silently translates it to a different and ineffective Podman option.
To Reproduce
- Create a directory containing only this
compose.yaml:
services:
test:
image: docker.io/library/busybox:latest
container_name: health-start-interval-repro
command: ["sh", "-c", "sleep 120"]
healthcheck:
test:
- CMD-SHELL
- "date +%s >> /tmp/healthcheck-times; exit 1"
interval: 30s
timeout: 2s
retries: 100
start_period: 10s
start_interval: 1s
The healthcheck always fails and records each execution time inside the
container. It intentionally keeps failing so that it remains in the startup
period for the full 10 seconds.
- Run:
$ podman-compose up -d
$ sleep 12
$ podman exec health-start-interval-repro \
sh -c 'cat /tmp/healthcheck-times; printf "count="; wc -l < /tmp/healthcheck-times'
- Clean up:
Expected behavior
According to the Compose Specification, the regular healthcheck should run
approximately every second during the 10-second start_period. After the
startup period, it should run every 30 seconds.
The output after 12 seconds should therefore contain approximately 10 health
check timestamps.
If the installed Podman version cannot implement Compose
healthcheck.start_interval, podman-compose should report the field as
unsupported with an explicit warning or error.
Compose Specification:
https://github.com/compose-spec/compose-spec/blob/main/spec.md#healthcheck
Actual behavior
The healthcheck does not run every second during start_period. On my
system, the output was:
The checks follow the normal interval instead. The generated
--health-startup-interval has no effect because no Podman startup
healthcheck command is configured.
Output
$ podman-compose version
podman-compose version 1.6.0
podman version 4.9.3
$ podman-compose up -d
d5550213217795690767e832a32565298d1ecf552b5398c27686d170065fc642
Trying to pull docker.io/library/busybox:latest...
Getting image source signatures
Copying blob b05093807bb0 done |
Copying config c6348fa86b done |
Writing manifest to image destination
c3754f331c11e41b810a8a290f1a10bb4eabaac3077f46dff97ea122a2e31da5
health-start-interval-repro
$ sleep 12
$ podman exec health-start-interval-repro \
sh -c 'cat /tmp/healthcheck-times; printf "count="; wc -l < /tmp/healthcheck-times'
1784066724
count=1
$ podman-compose down
health-start-interval-repro
health-start-interval-repro
d5550213217795690767e832a32565298d1ecf552b5398c27686d170065fc642
pc_test_default
Environment:
- OS: WSL
- Podman version: 4.9.3
- podman-compose version: 1.6.0
Additional context
Podman documents --health-startup-cmd and
--health-startup-interval as a separate startup-healthcheck mechanism:
https://github.com/podman-container-tools/podman/blob/v6.0.1/docs/source/markdown/podman-healthcheck.1.md#startup-healthcheck-vs-regular-healthcheck
Podman's regular --health-start-period documentation states that checks
continue to use --health-interval:
https://docs.podman.io/en/latest/markdown/podman-run.1.html
The missing Docker-compatible start_interval functionality in Podman itself
is tracked separately in:
podman-container-tools/podman#26505
A possible podman-compose resolution would be:
- Stop translating Compose
start_interval to
--health-startup-interval, because the semantics are different.
- Until Podman provides an exact equivalent, emit an explicit unsupported
warning or error.
- Once Podman supports the field, map it to the corresponding native
option/API field.
- (Optional) Add an integration test that verifies the actual execution timestamps,
rather than only checking the generated CLI arguments.
Describe the bug
podman-composeaccepts the Compose Specification fieldhealthcheck.start_interval, but it does not cause health checks to run atthat interval during
healthcheck.start_period.The current implementation maps:
to:
Source:
podman-compose/podman_compose.py
Lines 1534 to 1542 in 8156ab4
However, Podman's
--health-startup-intervalbelongs to Podman's separatestartup-healthcheck mechanism.
That mechanism is gated by
--health-startup-cmd.podman-composegenerates--health-cmd, but doesnot generate
--health-startup-cmd, so the startup interval does not createor affect a startup healthcheck.
More importantly, the two settings have different semantics:
start_intervalchanges the interval of the regular healthcheckduring
start_period.--health-startup-intervalcontrols a separate startup healthcheck,which stops after its configured success condition is met.
--health-start-period.Therefore, mapping
start_intervalto--health-startup-intervalis notequivalent to the Compose Specification, even if an
--health-startup-cmdwere also generated.This mapping was introduced as support for
start_intervalin #1271. Thecurrent unit test verifies the generated CLI argument, but does not verify
the resulting healthcheck schedule:
podman-compose/tests/unit/test_container_to_args.py
Lines 1165 to 1197 in 8156ab4
This is partly related to a missing Podman runtime feature, but the
podman-compose-specific bug is that it accepts the Compose field andsilently translates it to a different and ineffective Podman option.
To Reproduce
compose.yaml:The healthcheck always fails and records each execution time inside the
container. It intentionally keeps failing so that it remains in the startup
period for the full 10 seconds.
$ podman-compose downExpected behavior
According to the Compose Specification, the regular healthcheck should run
approximately every second during the 10-second
start_period. After thestartup period, it should run every 30 seconds.
The output after 12 seconds should therefore contain approximately 10 health
check timestamps.
If the installed Podman version cannot implement Compose
healthcheck.start_interval,podman-composeshould report the field asunsupported with an explicit warning or error.
Compose Specification:
https://github.com/compose-spec/compose-spec/blob/main/spec.md#healthcheck
Actual behavior
The healthcheck does not run every second during
start_period. On mysystem, the output was:
The checks follow the normal
intervalinstead. The generated--health-startup-intervalhas no effect because no Podman startuphealthcheck command is configured.
Output
Environment:
Additional context
Podman documents
--health-startup-cmdand--health-startup-intervalas a separate startup-healthcheck mechanism:https://github.com/podman-container-tools/podman/blob/v6.0.1/docs/source/markdown/podman-healthcheck.1.md#startup-healthcheck-vs-regular-healthcheck
Podman's regular
--health-start-perioddocumentation states that checkscontinue to use
--health-interval:https://docs.podman.io/en/latest/markdown/podman-run.1.html
The missing Docker-compatible
start_intervalfunctionality in Podman itselfis tracked separately in:
podman-container-tools/podman#26505
A possible
podman-composeresolution would be:start_intervalto--health-startup-interval, because the semantics are different.warning or error.
option/API field.
rather than only checking the generated CLI arguments.