README
¶
Dockadvisor
A fast, lightweight Dockerfile linter written in Go that helps you write better Dockerfiles by detecting common issues and anti-patterns.
Features
- Fast & Lightweight: Built with Go for optimal performance, with WebAssembly support for browser execution
- Comprehensive Validation: 60+ rules covering all standard Dockerfile instructions, multi-stage builds, and security best practices
- Clear Feedback: Actionable error messages with line numbers, severity levels, and links to Docker documentation
- Quality Scoring: Get a 0-100 score based on rule violations to track Dockerfile quality over time
- Security-Aware: Detects potential secrets in variables, validates ARG scoping, and checks for undefined references
Installation
Install CLI using Go
go install github.com/deckrun/dockadvisor/cmd/dockadvisor@latest
Build CLI from Source
git clone https://github.com/deckrun/dockadvisor.git
cd dockadvisor
make build
WebAssembly Build
# Build with standard Go compiler
make build-wasm
Usage
As a Web Interface

Run Dockadvisor using Docker Compose:
# Start the web interface using Docker Compose
docker compose up
And then access the application at http://localhost:3030
As a Go Library
package main
import (
"log"
"github.com/deckrun/dockadvisor/parse"
)
func main() {
dockerfileContent := `
FROM alpine:latest as builder
WORKDIR usr/app
RUN echo "Hello World"
`
result, err := parse.ParseDockerfile(dockerfileContent)
if err != nil {
log.Fatal("Error parsing Dockerfile:", err)
}
for _, rule := range result.Rules {
log.Printf("Line %d-%d: [%s] %s (Severity: %s)\n",
rule.StartLine,
rule.EndLine,
rule.Code,
rule.Description,
rule.Severity,
)
}
log.Printf("Dockerfile Score: %d/100\n", result.Score)
}
As a WebAssembly Module
// Load the WASM module
const go = new Go();
WebAssembly.instantiateStreaming(fetch("dockadvisor.wasm"), go.importObject)
.then((result) => {
go.run(result.instance);
// Call the parseDockerfile function
const dockerfileContent = `
FROM alpine:latest as builder
WORKDIR usr/app
`;
const result = parseDockerfile(dockerfileContent);
if (result.success) {
console.log("Score:", result.score);
console.log("Rules:", result.rules);
result.rules.forEach(rule => {
console.log(` ${rule.code} (${rule.severity}): ${rule.description}`);
});
} else {
console.error("Error:", result.error);
}
});
API Reference
ParseDockerfile
func ParseDockerfile(dockerfileContent string) (*Result, error)
Parses a Dockerfile and returns validation results.
Parameters:
dockerfileContent(string): The content of the Dockerfile to analyze
Returns:
*Result: Contains an array ofRuleobjects and a quality scoreerror: Error if parsing fails
Result Structure
type Result struct {
Rules []Rule // Array of rule violations
Score int // Quality score from 0-100 (100 = perfect)
}
Rule Structure
type Severity string
const (
SeverityError Severity = "error" // Build failures, invalid syntax
SeverityWarning Severity = "warning" // Best practices, style issues
)
type Rule struct {
StartLine int // Line where the issue starts
EndLine int // Line where the issue ends
Code string // Rule code (e.g., "FromAsCasing")
Description string // Human-readable description
Url string // Link to documentation
Severity Severity // Rule severity level
}
Scoring System
Dockadvisor calculates a quality score (0-100) based on the severity of detected issues:
- Perfect Dockerfile: Score of 100 (no violations)
- Error penalties: -15 points each (invalid syntax, build failures)
- Warning penalties: -5 points each (style issues, best practices)
- Minimum score: 0 (score is capped at zero)
Severity Classifications:
-
Errors (-15 points): Issues that will cause build failures or invalid syntax
InvalidInstruction,UndefinedVar,DuplicateStageName- Missing arguments, invalid formats
-
Warnings (-5 points): Best practices and style recommendations
FromAsCasing,WorkdirRelativePath,StageNameCasingSecretsUsedInArgOrEnv,MaintainerDeprecated
Example:
- Dockerfile with 2 errors and 3 warnings:
100 - (2×15) - (3×5) = 55/100
Validation Rules
Dockadvisor validates Dockerfiles against Docker best practices with comprehensive rule coverage.
Supported Instructions
All standard Dockerfile instructions are validated:
- FROM - Base image specification and multi-stage builds
- RUN - Execute commands during build
- WORKDIR - Set working directory
- EXPOSE - Document exposed ports
- CMD - Default command for container
- ENTRYPOINT - Configure container executable
- SHELL - Override default shell
- VOLUME - Create mount points
- USER - Set user and group
- LABEL - Add metadata key-value pairs
- ENV - Set environment variables
- ARG - Define build-time variables
- COPY - Copy files from build context
- ADD - Copy files with additional features
- HEALTHCHECK - Configure container health checks
- ONBUILD - Add trigger instructions for derived images
- STOPSIGNAL - Set signal to stop container
- MAINTAINER - Set author metadata (deprecated)
Rule Categories
Global Validation Rules
These rules apply across the entire Dockerfile:
- ConsistentInstructionCasing (Warning) - All instructions should use consistent casing (all uppercase or all lowercase)
- NoEmptyContinuation (Warning) - Empty lines following backslash continuations are deprecated
- DuplicateStageName (Error) - Stage names in multi-stage builds must be unique
- FromPlatformFlagConstDisallowed (Warning) - Platform flags should not use ARG variables as constant values
- JSONArgsRecommended (Warning) - CMD and ENTRYPOINT should use JSON array format for better signal handling
- UndefinedArgInFrom (Error) - ARG variables used in FROM must be defined before the FROM instruction
- UndefinedVar (Error) - Variables used in instructions must be defined via ARG or ENV
- MultipleInstructionsDisallowed (Error) - Only one CMD, HEALTHCHECK, or ENTRYPOINT allowed per stage
- SecretsUsedInArgOrEnv (Warning) - Sensitive variable names (password, token, secret, etc.) should not be defined in ARG or ENV
- InvalidDefaultArgInFrom (Error) - Default ARG values cannot be used in FROM instructions
Instruction-Specific Rules
FROM Instruction:
- FromMissingImage (Error) - FROM requires an image reference
- FromInvalidImageReference (Error) - Image reference format is invalid
- FromAsCasing (Warning) - 'AS' keyword should be lowercase
- StageNameCasing (Warning) - Stage names should be lowercase
- FromInvalidStageName (Error) - Stage name contains invalid characters
- ReservedStageName (Error) - Stage name cannot be 'context' or 'scratch' (reserved)
- FromInvalidPlatform (Error) - Platform flag format is invalid
- RedundantTargetPlatform (Warning) - TARGETPLATFORM variable is implicitly available
RUN Instruction:
- RunMissingCommand (Error) - RUN requires a command
- RunInvalidExecForm (Error) - Invalid JSON format for exec form
- RunInvalidMountFlag (Error) - Invalid --mount flag format
- RunInvalidNetworkFlag (Error) - Invalid --network flag value
- RunInvalidSecurityFlag (Error) - Invalid --security flag value
WORKDIR Instruction:
- WorkdirRelativePath (Warning) - WORKDIR should use absolute paths
EXPOSE Instruction:
- ExposeInvalidFormat (Error) - Port must be a number or range
- ExposePortOutOfRange (Error) - Port numbers must be 1-65535
- ExposeInvalidProtocol (Error) - Protocol must be tcp or udp
- ExposeProtoCasing (Warning) - Protocol should be lowercase
CMD Instruction:
- CmdMissingCommand (Error) - CMD requires a command
- CmdInvalidExecForm (Error) - Invalid JSON format for exec form
ENTRYPOINT Instruction:
- EntrypointMissingCommand (Error) - ENTRYPOINT requires a command
- EntrypointInvalidExecForm (Error) - Invalid JSON format for exec form
SHELL Instruction:
- ShellMissingConfig (Error) - SHELL requires shell configuration
- ShellRequiresJsonForm (Warning) - SHELL should use JSON array format
- ShellInvalidJsonForm (Error) - Invalid JSON format
VOLUME Instruction:
- VolumeMissingPath (Error) - VOLUME requires at least one path
- VolumeInvalidJsonForm (Error) - Invalid JSON format for volume paths
USER Instruction:
- UserMissingValue (Error) - USER requires a user name or UID
- UserInvalidFormat (Error) - Invalid user:group format
LABEL Instruction:
- LabelMissingKeyValue (Error) - LABEL requires key=value pairs
- LabelInvalidFormat (Error) - Invalid label format
ENV Instruction:
- EnvMissingKeyValue (Error) - ENV requires key=value pairs
- EnvInvalidFormat (Error) - Invalid environment variable format
- LegacyKeyValueFormat (Warning) - Use key=value format instead of legacy space-separated format
ARG Instruction:
- ArgMissingName (Error) - ARG requires a variable name
- ArgInvalidFormat (Error) - Invalid ARG format
COPY Instruction:
- CopyMissingArguments (Error) - COPY requires at least source and destination
- CopyInvalidFlag (Error) - Invalid flag for COPY instruction
ADD Instruction:
- AddMissingArguments (Error) - ADD requires at least source and destination
- AddInvalidFlag (Error) - Invalid flag for ADD instruction
HEALTHCHECK Instruction:
- HealthcheckMissingCmd (Error) - HEALTHCHECK CMD is required
ONBUILD Instruction:
- OnbuildMissingInstruction (Error) - ONBUILD requires a chained instruction
STOPSIGNAL Instruction:
- StopsignalMissingValue (Error) - STOPSIGNAL requires a signal value
MAINTAINER Instruction:
- MaintainerDeprecated (Warning) - MAINTAINER is deprecated, use LABEL maintainer=... instead
- MaintainerMissingName (Error) - MAINTAINER requires a name
Unrecognized Instructions:
- UnrecognizedInstruction (Error) - Instruction is not a valid Dockerfile instruction
Star History
Contributing
See CONTRIBUTING.md for guidelines on how to contribute to this project.
Related Projects
- hadolint - Haskell-based Dockerfile linter
- dockerfilelint - Node.js-based linter
- dockerfile-utils - TypeScript Dockerfile utilities
Support
- 📧 Report issues on GitHub Issues
- 💬 Join discussions on GitHub Discussions
Made with ❤️ for better Dockerfiles
Documentation
¶
There is no documentation for this package.