Skip to content

container: add --health-cmd-mode for CMD healthcheck form#7008

Open
lohitkolluri wants to merge 1 commit into
docker:masterfrom
lohitkolluri:fix/health-cmd-exec-3719
Open

container: add --health-cmd-mode for CMD healthcheck form#7008
lohitkolluri wants to merge 1 commit into
docker:masterfrom
lohitkolluri:fix/health-cmd-exec-3719

Conversation

@lohitkolluri
Copy link
Copy Markdown

@lohitkolluri lohitkolluri commented May 26, 2026

docker run/create always wraps --health-cmd in CMD-SHELL, which
fails on scratch and other shell-less images (#3719).

Add --health-cmd-mode with two values:

Value Behavior
shell (default) wraps command in CMD-SHELL — identical to existing behavior
exec uses the exec form (CMD), required for images without a shell

This mirrors the CMD / CMD-SHELL distinction in Dockerfile HEALTHCHECK instructions.

Usage

# exec form for scratch / distroless
docker run --health-cmd=/healthcheck --health-cmd-mode=exec my-image

# multi-argument exec form (parsed with shlex)
docker run --health-cmd='/usr/bin/wget -q -O /dev/null http://localhost/' \
           --health-cmd-mode=exec my-image

# explicit shell form — same as omitting --health-cmd-mode
docker run --health-cmd='curl -f http://localhost/' --health-cmd-mode=shell my-image

Test plan

  • go test ./cli/command/container/... -run TestParseHealth
  • make mddocs (docs regenerated in this commit)

Fixes #3719

@andrebrait
Copy link
Copy Markdown

How about an option --health-cmd-mode with values shell (the default) and exec?

Just in case the future has even more modes possible, so changing this is easier?

@andrebrait
Copy link
Copy Markdown

andrebrait commented May 26, 2026

Or cmd instead of exec, or upper-case, etc.

Up to the maintainers to know what they prefer, but I'm just throwing the idea out there.

@lohitkolluri lohitkolluri force-pushed the fix/health-cmd-exec-3719 branch from e09b71d to ec531ea Compare May 26, 2026 12:15
@lohitkolluri lohitkolluri changed the title container: add --health-cmd-exec for CMD healthcheck form container: add --health-cmd-mode for CMD healthcheck form May 26, 2026
@lohitkolluri
Copy link
Copy Markdown
Author

@andrebrait Great suggestion — updated to --health-cmd-mode with string values shell (default, keeps CMD-SHELL behavior) and exec (uses the CMD form). This is cleaner and leaves room for future modes.

Changes in the latest commit:

  • --health-cmd-exec bool--health-cmd-mode string (default "shell")
  • Error on unrecognised mode value
  • Tests updated for both modes + invalid-mode case
  • Docs regenerated via make mddocs

@lohitkolluri
Copy link
Copy Markdown
Author

@thaJeztah — when you have a moment, could you please take a review pass on this? Happy to address any feedback.

Thank you.

@lohitkolluri lohitkolluri force-pushed the fix/health-cmd-exec-3719 branch from ec531ea to 02221de Compare May 26, 2026 13:59
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

docker run/create always wrapped --health-cmd in CMD-SHELL, which fails
on scratch and other shell-less images. Add --health-cmd-mode=exec to
produce the exec (CMD) form, matching Dockerfile HEALTHCHECK CMD
behavior. The default "shell" preserves existing --health-cmd behavior
unchanged.

Fixes docker#3719

Signed-off-by: Lohit Kolluri <lohitkolluri@gmail.com>
@lohitkolluri lohitkolluri force-pushed the fix/health-cmd-exec-3719 branch from 02221de to 4c9f13d Compare May 26, 2026 14:47
@lohitkolluri
Copy link
Copy Markdown
Author

CI failure root-cause analysis and fixes

Two golangci-lint violations were identified and resolved.


1. revive/line-length-limitopts.go:266 exceeded 200 characters

Root cause: The --health-cmd-mode flag registration line was 201 characters, one over the project's 200-character limit enforced by the revive linter.

Fix: Shortened the flag description from:

"shell" wraps the command in CMD-SHELL, "exec" uses the exec form (CMD) required for shell-less images

to:

"shell" runs via CMD-SHELL, "exec" uses exec form (CMD) for shell-less images

The meaning is preserved; the line now sits at 173 characters.


2. gocycloTestParseHealth cyclomatic complexity 25 (limit 16)

Root cause: All --health-cmd-mode test cases (exec-mode single-arg, multi-arg, explicit shell, invalid mode, missing --health-cmd, unclosed quote, empty command, and --no-healthcheck conflict) were added to the existing TestParseHealth function. Each conditional and loop increments the cyclomatic complexity counter; the combined function exceeded the project's threshold of 16.

Fix: Extracted all --health-cmd-mode-specific cases into a dedicated TestParseHealthCmdMode function. TestParseHealth now covers only the pre-existing baseline healthcheck flags (--no-healthcheck, default CMD-SHELL mode, and the timing/retry options). TestParseHealthCmdMode covers the new flag's behaviour exhaustively. Both functions compile cleanly, all tests pass, and both are well under the complexity limit.

@lohitkolluri
Copy link
Copy Markdown
Author

Hi @thaJeztah — gentle follow-up when you have a moment.

The lint failures (revive line-length and gocyclo on TestParseHealth) have been fixed in the latest commit (shortened flag description, --health-cmd-mode cases moved to TestParseHealthCmdMode). I left a root-cause summary in an earlier comment on this PR for reference.

Could you please:

  1. Approve the workflow runs for this PR (fork workflows are currently waiting on maintainer approval), and
  2. Set the milestone to 29.5.3 so validate-milestone can pass — I don’t have permission to set milestones on this repository.

Happy to make any further changes if anything else comes up in review. Thank you for your time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Image from "scratch" has no shell, but passing the --health-cmd to docker run uses CMD-SHELL

4 participants