A linter for nginx configuration files with WASM plugin support, autofix, and a browser-based Web UI.
- 30+ built-in rules covering security, best practices, style, syntax, and deprecation
- Autofix — automatically fix problems with
--fix - WASM plugin system — extend with custom rules written in Rust and compiled to WebAssembly
- Web UI — lint interactively in the browser with real-time feedback
- Ignore comments — suppress specific warnings with inline annotations
- Configurable — customize rules, severity, and options via
.nginx-lint.toml - JSON output — machine-readable output for CI integration
- GitHub Actions integration — inline PR annotations with
--format github-actions
For a comprehensive getting started guide covering installation, configuration, CI integration, and more, see docs/guide.md or run nginx-lint guide.
You can also try it in the browser: Demo
# Lint a configuration file
nginx-lint /etc/nginx/nginx.conf
# Automatically fix problems
nginx-lint --fix /etc/nginx/nginx.conf
# Show why a rule exists
nginx-lint why server-tokens-enabled
# List all available rules
nginx-lint why --list# Lint a configuration file (replace TARGET_PATH with your config path)
TARGET_PATH=/etc/nginx/nginx.conf docker run --rm -v "$(dirname "$TARGET_PATH"):$(dirname "$TARGET_PATH"):ro" ghcr.io/walf443/nginx-lint:latest "$TARGET_PATH"
# Automatically fix problems (mount as read-write)
TARGET_PATH=/etc/nginx/nginx.conf docker run --rm -v "$(dirname "$TARGET_PATH"):$(dirname "$TARGET_PATH")" ghcr.io/walf443/nginx-lint:latest --fix "$TARGET_PATH"nginx-lint [OPTIONS] [FILE]...
nginx-lint <COMMAND>
| Flag | Description |
|---|---|
-o, --format <FORMAT> |
Output format: errorformat (default), json, or github-actions |
--fix |
Automatically fix problems |
-c, --config <FILE> |
Path to configuration file |
--context <CONTEXT> |
Parent context for partial configs (e.g., http,server) |
--plugins <DIR> |
Directory containing custom WASM plugins |
--color / --no-color |
Force or disable colored output |
--no-fail-on-warnings |
Only fail on errors, not warnings |
-v, --verbose |
Show verbose output |
--profile |
Show time spent per rule |
config — Configuration file management
nginx-lint config init # Generate default .nginx-lint.toml
nginx-lint config init -o custom.toml # Custom output path
nginx-lint config validate # Validate configurationwhy — Show detailed documentation for a rule
nginx-lint why server-tokens-enabled # Explain a rule
nginx-lint why --list # List all rulesGenerate a default configuration file with:
nginx-lint config initThis creates .nginx-lint.toml:
[color]
ui = "auto" # "auto", "always", or "never"
error = "red"
warning = "yellow"
[rules.server-tokens-enabled]
enabled = true
[rules.indent]
indent_size = "auto" # or a number like 4
[rules.deprecated-ssl-protocol]
allowed_protocols = ["TLSv1.2", "TLSv1.3"]
# Support non-standard directives from extension modules
[rules.invalid-directive-context]
additional_contexts = { server = ["rtmp"], upstream = ["rtmp"] }
[parser]
block_directives = ["rtmp", "application"]See the rules list for all available rules, or run nginx-lint why --list locally.
Suppress warnings using nginx-lint:ignore comments. Both a rule name and a reason are required.
Comment on the line before:
# nginx-lint:ignore server-tokens-enabled required by monitoring system
server_tokens on;Inline comment:
server_tokens on; # nginx-lint:ignore server-tokens-enabled required by monitoring systemWhen linting partial configuration files (e.g., included snippets), specify the parent context:
# nginx-lint:context http,server
location /api {
proxy_pass http://backend;
}This is equivalent to --context http,server on the command line.
nginx-lint automatically follows include directives and lints the included files as well. Both absolute paths and glob patterns (e.g. include /etc/nginx/conf.d/*.conf;) are supported.
In production, nginx configs often include files from a directory that is populated at runtime via symlinks (e.g. sites-enabled/), while the actual source files live elsewhere (e.g. sites-available/). You can configure path mappings in .nginx-lint.toml so that nginx-lint reads from the correct location:
[[include.path_map]]
from = "sites-enabled"
to = "sites-available"With this configuration, an include sites-enabled/*.conf; directive will be resolved as sites-available/*.conf during linting.
Key behaviors:
- Component-level matching —
fromis matched against exact path segments, sosites-enabledwill not matchasites-enabledorsites-enabled-old. - Multi-segment values —
from = "nginx/sites-enabled"matches consecutive path components. - Chained application — Multiple
[[include.path_map]]entries are applied in declaration order, with each mapping receiving the output of the previous one.
# Chained example: sites-enabled → sites-available → conf
[[include.path_map]]
from = "sites-enabled"
to = "sites-available"
[[include.path_map]]
from = "sites-available"
to = "conf"Try the Web UI online without installation: Demo
Start the browser-based linting interface locally:
nginx-lint web --openThe Web UI provides:
- Real-time linting as you type
- Interactive fix buttons for each issue
- "Fix All" to apply all fixes at once
- Rule documentation with bad/good examples
- In-browser configuration editing
- Runs entirely client-side via WebAssembly
You can use nginx-lint-action to run nginx-lint in your GitHub Actions workflow with inline PR annotations:
- uses: walf443/nginx-lint-action@v1
with:
files: /etc/nginx/nginx.confAlternatively, use --format github-actions directly to produce workflow commands:
nginx-lint --format github-actions /etc/nginx/nginx.confLoad custom WASM plugins from a directory:
nginx-lint --plugins ./my-plugins /etc/nginx/nginx.confEach .wasm file in the directory is loaded as a plugin. See the plugins/builtin/ directory for examples of how to write plugins using the nginx-lint-plugin SDK.
# Default build (CLI + builtin plugins)
cargo install --path .
# With web server support
cargo install --path . --features web-server
# Build with embedded WASM plugins instead of native (requires WASM toolchain)
make build-plugins
cargo install --path . --no-default-features --features cli,wasm-builtin-plugins| Feature | Description |
|---|---|
cli |
Command-line interface (default) |
native-builtin-plugins |
Compile builtin plugins as native Rust (default) |
wasm-builtin-plugins |
Embed builtin WASM plugins in the binary (requires make build-plugins) |
plugins |
Support loading external WASM plugins |
web-server |
Built-in web server for browser UI |
wasm |
WebAssembly target support |