A minimal, production-grade CLI tool for statically analyzing Dockerfiles to detect common inefficiencies, anti-patterns, and security issues.
- Static Analysis: Purely static analysis - never executes Docker builds
- Single Binary: Compiles to a single Go binary with no runtime dependencies
- CI/CD Ready: Clear exit codes (0, 1, 2) and JSON output for pipeline integration
- Configurable: Ignore specific rules via CLI flags or inline comments
- Security Focused: Detects secrets in ENV/ARG without exposing actual values
- Multi-stage Support: Correctly analyzes multi-stage Dockerfiles with per-stage rule evaluation
- Comprehensive Rules: 17 built-in rules covering base images, layer optimization, security, and best practices
Requires Go 1.22 or later (as specified in go.mod).
go install github.com/devblac/docker-lint/cmd/docker-lint@latestgit clone https://github.com/devblac/docker-lint.git
cd docker-lint
go build -o docker-lint ./cmd/docker-lintDownload the latest release from the Releases page.
docker-lint [flags] [file]| Flag | Short | Description |
|---|---|---|
--help |
-h |
Show help message |
--version |
-v |
Show version information |
--json |
-j |
Output findings as JSON |
--quiet |
-q |
Suppress informational messages (show only warnings and errors) |
--strict |
-s |
Treat warnings as errors (exit code 1 if any warnings) |
--ignore <rules> |
Comma-separated list of rule IDs to ignore | |
--rules |
List all available rules with descriptions |
# Analyze a Dockerfile
docker-lint Dockerfile
# Analyze from stdin
cat Dockerfile | docker-lint
# JSON output for CI integration
docker-lint --json Dockerfile > results.json
# Strict mode for CI (fail on warnings)
docker-lint --strict Dockerfile
# Ignore specific rules
docker-lint --ignore DL3006,DL3008 Dockerfile
# Suppress informational messages
docker-lint --quiet Dockerfile
# List all available rules
docker-lint --rulesDisable specific rules for the next line using comments:
# docker-lint ignore: DL3007
FROM ubuntu:latest
# docker-lint ignore: DL4002
# No USER instruction needed for this build stage| Code | Meaning |
|---|---|
| 0 | Success - no errors found (warnings allowed in non-strict mode) |
| 1 | Lint errors found, or warnings found in strict mode |
| 2 | Fatal error - file not found, permission denied, or parse error |
docker-lint includes 17 built-in rules organized into four categories.
| ID | Severity | Name | Description |
|---|---|---|---|
| DL3006 | Warning | Missing explicit image tag | Always tag the version of an image explicitly to ensure reproducible builds |
| DL3007 | Warning | Using 'latest' tag | Using 'latest' tag can lead to unpredictable builds as the image may change |
| DL3008 | Warning | Large base image | Consider using a smaller base image variant (slim, alpine) to reduce image size |
| ID | Severity | Name | Description |
|---|---|---|---|
| DL3009 | Warning | Package manager cache not cleaned | Clean package manager cache in the same RUN instruction to reduce image size |
| DL3010 | Warning | Consecutive RUN instructions | Combine consecutive RUN instructions to reduce the number of layers |
| DL3011 | Warning | Suboptimal layer ordering | Place instructions that change less frequently earlier to optimize layer caching |
| DL3012 | Warning | Package update without install | Combine package update with install in the same RUN instruction to avoid cache issues |
| ID | Severity | Name | Description |
|---|---|---|---|
| DL4000 | Warning | Potential secret in ENV | Avoid storing secrets in ENV instructions as they persist in the image layers |
| DL4001 | Warning | Potential secret in ARG | Avoid storing secrets in ARG instructions as they are visible in image history |
| DL4002 | Warning | No USER instruction | Containers should not run as root; specify a USER instruction |
| DL4003 | Warning | ADD with URL | Using ADD with URLs is discouraged; use curl or wget in RUN for better control |
| DL4004 | Warning | ADD where COPY would suffice | Use COPY instead of ADD when not extracting archives or fetching URLs |
| ID | Severity | Name | Description |
|---|---|---|---|
| DL3001 | Warning | Multiple CMD instructions | Only the last CMD instruction takes effect; multiple CMD instructions are likely a mistake |
| DL3002 | Warning | Multiple ENTRYPOINT instructions | Only the last ENTRYPOINT instruction takes effect; multiple ENTRYPOINT instructions are likely a mistake |
| DL3003 | Warning | WORKDIR with relative path | Use absolute paths in WORKDIR to avoid confusion about the current directory |
| DL5000 | Warning | Missing HEALTHCHECK | Add a HEALTHCHECK instruction to enable container health monitoring |
| DL5001 | Info | Wildcard in COPY/ADD source | Wildcard patterns in COPY/ADD may include unnecessary files, increasing build context size |
Human-readable output with file path, line number, severity, rule ID, and message:
Dockerfile:1:1: [warning] DL3007: Using 'latest' tag for image 'ubuntu' is not recommended
Suggestion: Pin to a specific version like 'ubuntu:<version>' for reproducible builds
Dockerfile:3:1: [warning] DL3010: Found 2 consecutive RUN instructions that could be combined
Suggestion: Combine RUN instructions using '&&' to reduce layers
Machine-readable JSON output for CI/CD integration:
{
"file": "Dockerfile",
"findings": [
{
"rule_id": "DL3007",
"severity": "warning",
"line": 1,
"column": 1,
"message": "Using 'latest' tag for image 'ubuntu' is not recommended",
"suggestion": "Pin to a specific version like 'ubuntu:<version>' for reproducible builds"
}
],
"summary": {
"total": 1,
"errors": 0,
"warnings": 1,
"info": 0
}
}The repository's CI workflow runs go test ./... -cover. Coverage uploads to Codecov are attempted only when a CODECOV_TOKEN secret is configured; otherwise the upload step is skipped while tests still gate the build.
- name: Lint Dockerfile
run: |
docker-lint --strict --json Dockerfile > lint-results.json
if [ $? -ne 0 ]; then
cat lint-results.json
exit 1
filint-dockerfile:
script:
- docker-lint --strict Dockerfile
allow_failure: falsestage('Lint Dockerfile') {
steps {
sh 'docker-lint --strict Dockerfile'
}
}See CONTRIBUTING.md for development setup, testing guidelines, and contribution process.
# Clone the repository
git clone https://github.com/devblac/docker-lint.git
cd docker-lint
# Install dependencies
go mod download
# Run tests
go test ./...
# Build
go build -o docker-lint ./cmd/docker-lint
# Run linter on itself
./docker-lint testdata/valid/minimal.Dockerfile