Dockerfile¶
Optional External Tool Augmentation¶
Consent-first external tooling
External tool execution is optional and disabled by default. Use
--enable-external-tools (CLI) or enable_external_tools=true (MCP)
to opt in. Missing tools should return recommendations; no automatic
installs occur during analysis.
| Tool | Default invocation | Output |
|---|---|---|
hadolint |
hadolint -f json - |
JSON |
Zen Principles¶
8 principles across 5 categories, drawn from Dockerfile Best Practices.
Configuration · 1 principle Correctness · 1 principle Performance · 2 principles Robustness · 1 principle Security · 3 principles
| Rule ID | Principle | Category | Severity | Dogma |
|---|---|---|---|---|
dockerfile-001 |
Avoid latest tags in base images | Security | 8 | ZEN-STRICT-FENCES |
dockerfile-002 |
Run containers as non-root user | Security | 9 | ZEN-STRICT-FENCES |
dockerfile-003 |
Prefer COPY over ADD unless extra features are needed | Correctness | 6 | ZEN-EXPLICIT-INTENT |
dockerfile-004 |
Declare HEALTHCHECK for production images | Robustness | 7 | ZEN-FAIL-FAST |
dockerfile-005 |
Use multi-stage builds for compiled workloads | Performance | 6 | ZEN-PROPORTIONATE-COMPLEXITY |
dockerfile-006 |
Keep secrets out of ENV and ARG instructions | Security | 9 | ZEN-STRICT-FENCES |
dockerfile-007 |
Maintain layer discipline | Performance | 5 | ZEN-PROPORTIONATE-COMPLEXITY |
dockerfile-008 |
Keep .dockerignore coherent with broad context copies | Configuration | 4 | ZEN-EXPLICIT-INTENT |
dockerfile-001 — Avoid latest tags in base images
Pin base image versions to avoid unplanned upgrades.
Universal Dogmas: ZEN-STRICT-FENCES
Common Violations:
- FROM image:latest
Detectable Patterns:
:latest
Recommended Fix
Use explicit version tags like ubuntu:22.04.
dockerfile-002 — Run containers as non-root user
Final image should set a non-root USER directive.
Universal Dogmas: ZEN-STRICT-FENCES
Common Violations:
- Missing USER directive
- Final USER is root
Detectable Patterns:
USER root
Recommended Fix
Create and switch to an unprivileged runtime user.
dockerfile-003 — Prefer COPY over ADD unless extra features are needed
ADD has surprising behavior for archives and remote URLs.
Universal Dogmas: ZEN-EXPLICIT-INTENT
Common Violations:
- Using ADD for plain local copy
Detectable Patterns:
ADD
Recommended Fix
Use COPY for local files and reserve ADD for tar/URL use cases.
dockerfile-004 — Declare HEALTHCHECK for production images
Health checks improve orchestration reliability and recovery.
Universal Dogmas: ZEN-FAIL-FAST
Common Violations:
- Missing HEALTHCHECK instruction
Detectable Patterns:
!HEALTHCHECK
dockerfile-005 — Use multi-stage builds for compiled workloads
Compiled builds should separate build and runtime stages.
Universal Dogmas: ZEN-PROPORTIONATE-COMPLEXITY
Common Violations:
- Single-stage Dockerfile for compiled build commands
dockerfile-006 — Keep secrets out of ENV and ARG instructions
Credentials in Dockerfile instructions leak into image metadata/layers.
Universal Dogmas: ZEN-STRICT-FENCES
Common Violations:
- ENV with secret-like key
- ARG with credential-like key
dockerfile-007 — Maintain layer discipline
Excessive RUN layers increase image size and cache fragmentation.
Universal Dogmas: ZEN-PROPORTIONATE-COMPLEXITY
Common Violations:
- Too many RUN instructions
Thresholds:
| Parameter | Default |
|---|---|
max_run_instructions |
5 |
dockerfile-008 — Keep .dockerignore coherent with broad context copies
Broad context copies should be paired with .dockerignore hygiene.
Universal Dogmas: ZEN-EXPLICIT-INTENT
Common Violations:
- COPY/ADD from build context without .dockerignore
Detectable Patterns:
COPY .ADD .
Detector Catalog¶
Configuration¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| DockerfileDockerignoreDetector | Warns when broad context copies are used without a .dockerignore file |
dockerfile-008 |
Correctness¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| DockerfileAddInstructionDetector | Discourages broad ADD usage when COPY is sufficient |
dockerfile-003 |
Performance¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| DockerfileMultiStageDetector | Advises multi-stage builds when compiled build commands are detected | dockerfile-005 |
| DockerfileLayerDisciplineDetector | Limits excessive RUN layer count in Dockerfiles |
dockerfile-007 |
Robustness¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| DockerfileHealthcheckDetector | Reports Dockerfiles that do not declare a HEALTHCHECK instruction |
dockerfile-004 |
Security¶
| Detector | What It Catches | Rule IDs |
|---|---|---|
| DockerfileLatestTagDetector | Flags FROM instructions that pin to the mutable latest tag |
dockerfile-001 |
| DockerfileNonRootUserDetector | Ensures the final Docker runtime user is not root | dockerfile-002 |
| DockerfileSecretHygieneDetector | Detects secret-like keys embedded in ENV and ARG declarations |
dockerfile-006 |
Principle → Detector Wiring
%%{init: {"theme": "base", "flowchart": {"useMaxWidth": false, "htmlLabels": true, "nodeSpacing": 40, "rankSpacing": 60}}}%%
graph TD
dockerfile_001["dockerfile-001<br/>Avoid latest tags in base..."]
dockerfile_002["dockerfile-002<br/>Run containers as non-roo..."]
dockerfile_003["dockerfile-003<br/>Prefer COPY over ADD unle..."]
dockerfile_004["dockerfile-004<br/>Declare HEALTHCHECK for p..."]
dockerfile_005["dockerfile-005<br/>Use multi-stage builds fo..."]
dockerfile_006["dockerfile-006<br/>Keep secrets out of ENV a..."]
dockerfile_007["dockerfile-007<br/>Maintain layer discipline"]
dockerfile_008["dockerfile-008<br/>Keep .dockerignore cohere..."]
det_DockerfileAddInstructionDetector["Dockerfile Add<br/>Instruction"]
dockerfile_003 --> det_DockerfileAddInstructionDetector
det_DockerfileDockerignoreDetector["Dockerfile Dockerignore"]
dockerfile_008 --> det_DockerfileDockerignoreDetector
det_DockerfileHealthcheckDetector["Dockerfile Healthcheck"]
dockerfile_004 --> det_DockerfileHealthcheckDetector
det_DockerfileLatestTagDetector["Dockerfile Latest<br/>Tag"]
dockerfile_001 --> det_DockerfileLatestTagDetector
det_DockerfileLayerDisciplineDetector["Dockerfile Layer<br/>Discipline"]
dockerfile_007 --> det_DockerfileLayerDisciplineDetector
det_DockerfileMultiStageDetector["Dockerfile Multi<br/>Stage"]
dockerfile_005 --> det_DockerfileMultiStageDetector
det_DockerfileNonRootUserDetector["Dockerfile Non<br/>Root User"]
dockerfile_002 --> det_DockerfileNonRootUserDetector
det_DockerfileSecretHygieneDetector["Dockerfile Secret<br/>Hygiene"]
dockerfile_006 --> det_DockerfileSecretHygieneDetector
Detector Class Hierarchy
%%{init: {"theme": "base"}}%%
classDiagram
direction TB
class ViolationDetector {
<<abstract>>
+detect(context, config)
}
class det_01["Dockerfile Add Instruction"]
ViolationDetector <|-- det_01
class det_02["Dockerfile Dockerignore"]
ViolationDetector <|-- det_02
class det_03["Dockerfile Healthcheck"]
ViolationDetector <|-- det_03
class det_04["Dockerfile Latest Tag"]
ViolationDetector <|-- det_04
class det_05["Dockerfile Layer Discipline"]
ViolationDetector <|-- det_05
class det_06["Dockerfile Multi Stage"]
ViolationDetector <|-- det_06
class det_07["Dockerfile Non Root User"]
ViolationDetector <|-- det_07
class det_08["Dockerfile Secret Hygiene"]
ViolationDetector <|-- det_08
Analysis Pipeline
%%{init: {"theme": "base", "flowchart": {"useMaxWidth": false, "htmlLabels": true, "nodeSpacing": 50, "rankSpacing": 70}}}%%
flowchart TD
Source(["Source Code"]) --> Parse["Parse & Tokenize"]
Parse --> Metrics["Compute Metrics"]
Metrics --> Pipeline{"8 Detectors"}
Pipeline --> Collect["Aggregate Violations"]
Collect --> Result(["AnalysisResult<br/>8 principles"])
Analysis States
%%{init: {"theme": "base"}}%%
stateDiagram-v2
[*] --> Ready
Ready --> Parsing : analyze(code)
Parsing --> Computing : AST ready
Computing --> Detecting : metrics ready
Detecting --> Reporting : 8 detectors run
Reporting --> [*] : AnalysisResult
Parsing --> Reporting : parse error (best-effort)
Configuration¶
See Also¶
- Configuration — Per-language pipeline overrides
- Understanding Violations — Severity scale reference