| Property | Value |
|---|---|
| Severity | Info |
| Category | Performance |
| Default | Enabled |
| Auto-fix | Yes (--fix --fix-unsafe) |
Description
Suggests replacingRUN echo/cat/printf > file patterns with COPY <<EOF syntax for better performance and readability.
This rule detects file creation patterns in RUN instructions and extracts them into COPY heredocs, even when mixed with other commands.
It relies on Dockerfile here-documents support for COPY.
Why COPY heredoc?
- Performance:
COPYdoesn’t spawn a shell container, making it faster - Atomicity:
COPY --chmodsets permissions in a single layer - Readability: Heredocs are cleaner than escaped echo statements
Detected Patterns
- Simple file creation:
echo "content" > /path/to/file - printf with escape sequences:
printf 'line1\nline2\n' > /path/to/file - File creation with chmod:
echo "x" > /file && chmod 0755 /file - BuildKit heredoc piped to cat:
RUN <<EOF cat > /path/to/file - BuildKit heredoc piped to tee:
RUN <<EOF tee /path/to/file - Consecutive RUN instructions writing to the same file
- Mixed commands with file creation in the middle (extracts just the file creation)
Examples
Before (violation)
After (fixed with —fix —fix-unsafe)
Limitations
- Skips append operations (
>>) since COPY would change semantics - Skips relative paths (only absolute paths like
/etc/file) - Skips commands with shell variables not defined as ARG/ENV
Mount Handling
SinceCOPY doesn’t support --mount flags, the rule handles RUN mounts carefully:
| Mount Type | Behavior |
|---|---|
bind | Skip - content might depend on bound files |
cache | Safe if file target is outside cache path |
tmpfs | Safe if file target is outside tmpfs path |
secret | Safe if file target is outside secret path |
ssh | Safe - no content dependency |
Chmod Support
Converts both octal and symbolic chmod modes toCOPY --chmod:
- Octal:
chmod 755→--chmod=0755 - Symbolic:
chmod +x→--chmod=0755,chmod u+x→--chmod=0744
Options
| Option | Type | Default | Description |
|---|---|---|---|
check-single-run | boolean | true | Check for single RUN instructions with file creation |
check-consecutive-runs | boolean | true | Check for consecutive RUN instructions to same file |
Configuration
Rule Coordination
This rule takes priority overprefer-run-heredoc for pure file creation patterns. When both rules detect a pattern, prefer-copy-heredoc handles
it.