No description
Find a file
2026-06-09 14:41:15 +08:00
examples update 2026-06-05 14:19:38 +08:00
fastcgi update 2026-06-09 14:41:15 +08:00
http update 2026-06-09 14:41:15 +08:00
listen update 2026-06-09 14:41:15 +08:00
proxy_pass update 2026-06-09 14:41:15 +08:00
redirect update 2026-06-09 14:41:15 +08:00
scripts update 2026-06-09 14:41:15 +08:00
ssl update 2026-06-09 14:41:15 +08:00
templates/cert update 2026-06-09 14:41:15 +08:00
README.md update 2026-06-09 14:41:15 +08:00
security-legacy.conf update 2026-06-09 14:41:15 +08:00
security.conf update 2026-06-09 14:41:15 +08:00

Nginx Kit

Start

git clone https://git.forge.st/ops/nginx-kit.git /opt/nginx-kit
ln -s /opt/nginx-kit /etc/nginx/kit

Update

cd /opt/nginx-kit
git pull
nginx -t
systemctl reload nginx

Contexts

This repository is organized by nginx context:

  • http/: snippets that must be included inside http {}.
  • listen/: listener snippets for server {} blocks.
  • fastcgi/: FastCGI-specific snippets for location {} or server {} blocks.
  • ssl/: HTTPS and TLS snippets for server {} blocks.
  • proxy_pass/: reverse proxy snippets for location {} blocks.
  • redirect/: host and canonical URL redirects for server {} blocks.
  • templates/: copy-and-edit starter snippets such as certificates.
  • examples/: working examples showing how to compose the snippets.

Common combinations

HTTPS site

Include these inside a server {} block:

server {
	# ...
	include kit/listen/http.conf;
	include kit/listen/https-http2.conf;
	include snippets/cert/mydomain.com.conf;
	include kit/security.conf;
	include kit/ssl/security.conf;
	include kit/ssl/hsts.conf;
	include kit/ssl/force.conf;
	# ...
}

See examples/example.com.conf for the full server-level example.

For widest compatibility, the examples use listen ... http2 instead of the standalone http2 on; directive. The standalone http2 directive appeared in nginx 1.25.1 on 2023-06-13, while Ubuntu-packaged nginx 1.24.x rejects it.

For nginx 1.25.1+, you can use the modern split form instead:

server {
	include kit/listen/http.conf;
	include kit/listen/https.conf;
	include kit/listen/http2.conf;
	# ...
}

Optional http {} features

These snippets are independent http {}-level features:

http {
	include kit/http/gzip.conf;
}

Use kit/http/gzip.conf when you want nginx to compress common text-based responses. It is not specific to proxying or websocket traffic.

http {
	include kit/http/websocket-map.conf;
}

Use kit/http/websocket-map.conf only when a location {} will include kit/proxy_pass/websocket.conf.

http {
	include kit/http/log-format-upstream.conf;
}

Use kit/http/log-format-upstream.conf when you want a reusable access log format with upstream timing fields. It only defines upstream_timing; each server still opts in with its own access_log directive.

Reverse proxy

Plain HTTP reverse proxying only needs the location {}-level proxy snippets:

server {
	# ...
	include kit/listen/http.conf;
	location / {
		include kit/proxy_pass/forwarded.conf;
		include kit/proxy_pass/timeout-300.conf;
		proxy_pass http://app_backend;
	}
}

Streaming reverse proxy

For SSE, token streaming, or other incremental responses, add the streaming and long-timeout snippets to the proxied location:

http {
	include kit/http/log-format-upstream.conf;

	server {
		include kit/listen/http.conf;
		access_log /var/log/nginx/app.access.log upstream_timing;

		location /events/ {
			include kit/proxy_pass/forwarded.conf;
			include kit/proxy_pass/streaming.conf;
			include kit/proxy_pass/timeout-300.conf;
			proxy_pass http://app_backend;
		}
	}
}

Use kit/proxy_pass/streaming.conf only for locations that genuinely need incremental flushing. It intentionally changes buffering behavior and forces HTTP/1.1 for that location.

Websocket reverse proxy

Websocket proxying adds one http {}-level dependency plus the websocket location snippet:

http {
	include kit/http/websocket-map.conf;

	server {
		include kit/listen/http.conf;
		include kit/listen/https-http2.conf;
		location /ws/ {
			include kit/proxy_pass/forwarded.conf;
			include kit/proxy_pass/websocket.conf;
			include kit/proxy_pass/timeout-300.conf;
			proxy_pass http://app_backend;
		}
	}
}

See examples/reverse-proxy.nginx.conf for a complete standalone config.

Templates

SSL certs

cd /etc/nginx
mkdir -p snippets/cert
cp kit/templates/cert/example.com.conf snippets/cert/mydomain.com.conf
vi snippets/cert/mydomain.com.conf

Replace the certificate paths with yours, then include the snippet in your server {} block:

server {
	# ...
	include snippets/cert/mydomain.com.conf;
	include kit/security.conf;
	include kit/ssl/security.conf;
	include kit/ssl/hsts.conf;
	# ...
}

Snippet reference

  • kit/http/gzip.conf: gzip compression for common text-based responses. Must be included inside http {}.
  • kit/http/log-format-upstream.conf: defines the upstream_timing access log format with upstream timing fields. Must be included inside http {}.
  • kit/http/websocket-map.conf: defines $connection_upgrade for websocket proxying. Must be included inside http {}.
  • kit/listen/http.conf: IPv4 and IPv6 HTTP listeners for server {}.
  • kit/listen/https.conf: IPv4 and IPv6 HTTPS listeners for server {} without enabling HTTP/2.
  • kit/listen/http2.conf: standalone http2 on; snippet for nginx 1.25.1+.
  • kit/listen/https-http2.conf: IPv4 and IPv6 HTTPS listeners with HTTP/2 for server {}. Uses listen ... http2 for nginx 1.24.x compatibility.
  • kit/security.conf: common low-risk security headers and host normalization. Intended for server {}.
  • kit/security-legacy.conf: optional legacy compatibility headers such as X-Download-Options and X-Permitted-Cross-Domain-Policies.
  • kit/fastcgi/hide-powered-by.conf: hides X-Powered-By from FastCGI upstream responses.
  • kit/fastcgi/timeout-300.conf: longer FastCGI timeouts. Intended for location {}.
  • kit/ssl/security.conf: TLS protocol and session resumption settings. Intended for server {}.
  • kit/ssl/hsts.conf: HSTS header for HTTPS responses. Intended for server {}.
  • kit/ssl/hsts-preload.conf: HSTS variant with preload. Use only if the whole domain tree is preload-safe.
  • kit/ssl/force.conf: redirects HTTP requests to HTTPS. Intended for server {}.
  • kit/redirect/to-primary-domain.conf: redirects aliases to the primary server_name. Intended for server {}.
  • kit/proxy_pass/forwarded.conf: standard reverse proxy headers. Intended for location {}.
  • kit/proxy_pass/hide-powered-by.conf: hides X-Powered-By from proxied upstream responses.
  • kit/proxy_pass/https-upstream.conf: enables SNI for HTTPS upstreams. Intended for location {}.
  • kit/proxy_pass/streaming.conf: disables proxy buffering for streaming responses and requests. Intended for location {}.
  • kit/proxy_pass/websocket.conf: websocket upgrade headers. Requires kit/http/websocket-map.conf.
  • kit/proxy_pass/timeout-300.conf: longer proxy timeouts. Intended for location {}.

Validation

Run the Docker-based syntax checks from the repo root:

./scripts/validate-docker.ps1

The script validates:

Notes

  • gzip_proxied does not remove ETag or Last-Modified headers. It only controls when nginx may gzip requests that arrived through another proxy.
  • text/html does not need to appear in gzip_types; nginx compresses it automatically.
  • Gzip over HTTPS can contribute to BREACH-style risk for responses that reflect attacker-controlled input alongside secrets. Keep that in mind for highly sensitive dynamic pages.
  • kit/security.conf intentionally does not set X-Robots-Tag: none or X-XSS-Protection: 1; mode=block; those are too risky or too obsolete for a default site-wide baseline.
  • The standalone http2 on; directive appeared in nginx 1.25.1 on 2023-06-13. For broader compatibility, this repository currently prefers listen 443 ssl http2; and listen [::]:443 ssl http2;.
  • If you are standardizing on nginx 1.25.1+, prefer kit/listen/https.conf plus kit/listen/http2.conf to avoid the deprecation warnings on modern nginx.
  • Listener snippets are intentionally minimal. Variants such as default_server, proxy_protocol, or non-HTTP/2 HTTPS should live in separate project-specific snippets to avoid accidental conflicts.