An open API service indexing awesome lists of open source software.

https://github.com/walf443/nginx-lint

A linter for nginx configuration files with WASM plugin support
https://github.com/walf443/nginx-lint

nginx

Last synced: 4 months ago
JSON representation

A linter for nginx configuration files with WASM plugin support

Awesome Lists containing this project

README

          

# nginx-lint

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

A linter for nginx configuration files with WASM plugin support, autofix, and a browser-based Web UI.

## Features

- **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`

## Quick Start

You can also try it in the browser: [Demo](https://walf443.github.io/nginx-lint/)

```bash
# 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
```

### Docker

```bash
# 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"
```

## Usage

```
nginx-lint [OPTIONS] [FILE]...
nginx-lint
```

### Options

| Flag | Description |
|------|-------------|
| `-o, --format ` | Output format: `errorformat` (default), `json`, or `github-actions` |
| `--fix` | Automatically fix problems |
| `-c, --config ` | Path to configuration file |
| `--context ` | Parent context for partial configs (e.g., `http,server`) |
| `--plugins ` | 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 |

### Subcommands

**`config`** — Configuration file management

```bash
nginx-lint config init # Generate default .nginx-lint.toml
nginx-lint config init -o custom.toml # Custom output path
nginx-lint config validate # Validate configuration
```

**`why`** — Show detailed documentation for a rule

```bash
nginx-lint why server-tokens-enabled # Explain a rule
nginx-lint why --list # List all rules
```

## Configuration

Generate a default configuration file with:

```bash
nginx-lint config init
```

This creates `.nginx-lint.toml`:

```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"]
```

## Rules

See the [rules list](https://walf443.github.io/nginx-lint/rules.html) for all available rules, or run `nginx-lint why --list` locally.

## Ignore Comments

Suppress warnings using `nginx-lint:ignore` comments. Both a rule name and a reason are required.

**Comment on the line before:**

```nginx
# nginx-lint:ignore server-tokens-enabled required by monitoring system
server_tokens on;
```

**Inline comment:**

```nginx
server_tokens on; # nginx-lint:ignore server-tokens-enabled required by monitoring system
```

### Context Comments

When linting partial configuration files (e.g., included snippets), specify the parent context:

```nginx
# nginx-lint:context http,server
location /api {
proxy_pass http://backend;
}
```

This is equivalent to `--context http,server` on the command line.

## Include Resolution

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.

### Path Mapping

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:

```toml
[[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** — `from` is matched against exact path segments, so `sites-enabled` will not match `asites-enabled` or `sites-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.

```toml
# Chained example: sites-enabled → sites-available → conf
[[include.path_map]]
from = "sites-enabled"
to = "sites-available"

[[include.path_map]]
from = "sites-available"
to = "conf"
```

## Web UI

Try the Web UI online without installation: [Demo](https://walf443.github.io/nginx-lint/)

Start the browser-based linting interface locally:

```bash
nginx-lint web --open
```

The 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

## GitHub Actions

You can use [nginx-lint-action](https://github.com/walf443/nginx-lint-action) to run nginx-lint in your GitHub Actions workflow with inline PR annotations:

```yaml
- uses: walf443/nginx-lint-action@v1
with:
files: /etc/nginx/nginx.conf
```

Alternatively, use `--format github-actions` directly to produce workflow commands:

```bash
nginx-lint --format github-actions /etc/nginx/nginx.conf
```

## Custom Plugins

Load custom WASM plugins from a directory:

```bash
nginx-lint --plugins ./my-plugins /etc/nginx/nginx.conf
```

Each `.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.

## Installation

### From source

```bash
# 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
```

### Cargo features

| 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 |

## License

[MIT](LICENSE)