Catches Dockerfile layer caching issues that slow down your builds.
Changed one line of code and Docker rebuilt everything? Probably something in your Dockerfile breaking the layer cache. This tool finds those issues.
It checks for stuff like:
- Copying everything before
npm install(so every code change reinstalls packages) - Using
FROM node:latest(reproducibility nightmare) - Running as root (security issue)
- Missing
.dockerignore(slow builds, leaks secrets)
Takes a second to run, tells you exactly what's broken and how to fix it.
Quick:
curl -sSL https://raw.githubusercontent.com/vviveksharma/layerLint/main/install.sh | shManual: Grab a binary from releases or build it:
git clone https://github.com/vviveksharma/layerLint
cd layerLint
make generate-buildmacOS/Linux (.tar.gz):
- Extract the downloaded file:
tar -xzf layerLint_*.tar.gz- Make it executable:
chmod +x layerlint- Option A - Install globally (recommended):
# Move to system PATH
sudo mv layerlint /usr/local/bin/
# Or create a symlink (keeps original location)
sudo ln -s $(pwd)/layerlint /usr/local/bin/layerlintNow use anywhere:
layerlint scan --dockerfile Dockerfile- Option B - Run from current directory:
./layerlint scan --dockerfile DockerfileWindows (.zip):
-
Extract the zip file (Right-click → Extract All)
-
Option A - Add to PATH:
- Move
layerlint.exetoC:\Program Files\LayerLint\ - Add to system PATH:
- Search "Environment Variables" in Start menu
- Edit "Path" variable
- Add
C:\Program Files\LayerLint\
- Restart terminal and use anywhere:
layerlint scan --dockerfile Dockerfile
- Move
-
Option B - Run from current directory:
layerlint.exe scan --dockerfile DockerfileVerify Installation:
layerlint --version
layerlint scan --help./layerlint scan --dockerfile DockerfileThat's it. You'll see what's broken and how to fix it.
Report formats:
# Text output (default)
./layerlint scan --dockerfile Dockerfile
# JSON (for scripts/CI)
./layerlint scan --dockerfile Dockerfile --format json --output report.json
# SARIF (GitHub Security tab)
./layerlint scan --dockerfile Dockerfile --format sarif --output results.sarif
# HTML (for artifacts)
./layerlint scan --dockerfile Dockerfile --format html --output report.htmlSee Report Generation Guide for details.
Basic workflow:
name: Lint Dockerfile
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install LayerLint
run: |
curl -sSL https://github.com/vviveksharma/layerLint/releases/latest/download/layerLint_Linux_x86_64.tar.gz | tar xz
chmod +x layerlint
- name: Scan Dockerfile
run: ./layerlint scan --dockerfile ./Dockerfile --fail-on-severity highReady-to-use examples in .github/workflows/examples/:
- example-basic-lint.yml - Simple scan
- example-multi-dockerfile.yml - Scan multiple Dockerfiles
- example-build-deploy.yml - Lint then build/push
- example-scheduled-audit.yml - Weekly audit with issue creation
For GitLab CI, CircleCI, Jenkins, Azure Pipelines, etc., see the CI/CD Integration Guide. Has working examples for all of them.
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: layerlint
name: LayerLint
entry: layerlint scan --dockerfile
language: system
files: Dockerfile.*
pass_filenames: trueGot test Dockerfiles in testFiles/ that break each rule on purpose. Try them:
./layerlint scan --dockerfile testFiles/broad-copy-before-deps-failureOr run all:
for file in testFiles/*-failure; do
echo "Testing: $file"
./layerlint scan --dockerfile "$file"
doneEach file triggers at least one violation. Useful for seeing what not to do.
This kills build performance. Don't do this:
FROM golang:1.22
COPY . . # Copies everything
RUN go mod download # Every code change = re-download depsDo this instead:
FROM golang:1.22
COPY go.mod go.sum ./ # Just dependency files
RUN go mod download # Cached unless go.mod changes
COPY . . # Now copy sourceSame pattern for npm, pip, poetry, etc. Copy dependency manifest first, install, then copy source.
Check the rules documentation for the complete list. Quick summary:
unpinned-base-image-tag- Using:latestinstead of specific versionsapt-update-without-install- Creates stale cache layerscopying-secrets-into-image- Don't bake secrets into imagesrun-as-root- Security issuebuild-without-cache-mount- Missing BuildKit cache mountswget-curl-without-checksum- Supply chain risk- Plus a few more...
When it finds issues:
RuleID: dockerfile/broad-copy-before-deps
Severity: high
File: Dockerfile
Line: 4
Title: Dependency install runs after broad source copy
Message: This dependency step runs after a broad COPY/ADD, so source changes can invalidate the dependency cache.
Suggestion: Copy dependency manifests first, install dependencies, then copy the rest of the source.
Pretty clear what's wrong and how to fix it.
Code's straightforward. Rules are in internal/rules/, each one is its own file. To add a new rule:
- Create a file in
internal/rules/ - Implement the
Ruleinterface (ID()andCheck()) - Register it in
internal/scanner/scaner.go - Add a test file in
testFiles/
Look at broad_copy_before_deps.go for an example. Build: make generate-build
Got tired of slow builds because of bad Dockerfiles. Wrote this instead of explaining the same caching issues repeatedly.
- Rules Documentation - What each rule checks
- CI/CD Integration - Platform-specific examples
- Report Generation - JSON/SARIF/HTML outputs
- Releases - Download binaries
MIT License.
