| Property | Value |
|---|---|
| Severity | Style |
| Category | Style |
| Default | Enabled |
| Auto-fix | Yes (--fix) |
Description
Suggests converting multi-command RUN instructions to heredoc syntax for better readability. This rule targets Dockerfile here-documents withRUN, which are supported by BuildKit syntax.
Shell-specific heredoc bodies are supported too:
- POSIX shells keep the usual multi-line heredoc body with
set -eand optionalset -o pipefail - PowerShell heredocs use a multi-line body with
$ErrorActionPreference = 'Stop'plus explicit guards between commands. This applies topowershellon Windows andpwshon cross-platform images. cmd.exeheredocs are supported, but real WCOW builds only executed chained bodies reliably when the body stayed on one logical line, so the fixer emits a grouped single-line(...)command list inside the heredoc
- Multiple consecutive RUN instructions that could be combined
- Single RUN with chained commands via
&&(3+ commands by default)
Why heredoc?
Heredoc syntax for RUN instructions offers:- Readability: Each command on its own line, no
&&or\clutter - Maintainability: Easy to add, remove, or reorder commands
- Debugging: Clear line numbers in error messages
Examples
Before (violation)
After (fixed with —fix)
Another real-life example
Why set -e?
Heredocs don’t stop on error by default - only the exit code of the last command matters. Adding set -e preserves the fail-fast behavior of &&
chains.
See moby/buildkit#2722 for details.
For non-POSIX shells, the fixer preserves the same intent with shell-native
behavior instead of set -e:
- PowerShell gets
$ErrorActionPreference = 'Stop'and$PSNativeCommandUseErrorActionPreference = $true cmd.exekeeps the original&&semantics inside a grouped command block
Options
| Option | Type | Default | Description |
|---|---|---|---|
min-commands | integer | 3 | Minimum commands to trigger (heredocs add 2 lines overhead) |
check-consecutive-runs | boolean | true | Check for consecutive RUN instructions |
check-chained-commands | boolean | true | Check for && chains in single RUN |
Configuration
Rule Coordination
When this rule is enabled,hadolint/DL3003 (cd → WORKDIR) will skip generating fixes for commands that are heredoc candidates, allowing heredoc
conversion to handle cd correctly within the script.
On Windows, this rule also collaborates with tally/powershell/prefer-shell-instruction:
- if repeated
RUN powershell ...orRUN pwsh ...wrappers are first normalized into a PowerShellSHELL, this rule will then see the rewrittenRUNinstructions under the effective PowerShell shell - that lets a
cmd-styleRUN powershell ... && ...sequence become a proper PowerShell heredoc instead of falling back to acmd.exeheredoc body - the same pass can also absorb immediately following PowerShell-safe
RUNinstructions, so a stage can end up with one larger PowerShell heredoc after theSHELLrewrite