Nginx and Caddy Config Generator
Fill in a domain and an upstream, get a working nginx server block and an equivalent Caddyfile side by side, with TLS, headers, and rate limiting.
Privacy: Everything runs in your browser. Your domains, upstreams, and file paths are never uploaded or logged.
nginx.conf
Caddyfile
Generated entirely in your browser — nothing is uploaded. Run nginx -t or caddy validate before you reload, and read the comments: a few directives need modules or plugins that are not in the stock builds.
What it does
You describe the site once — domains, whether it proxies to an app or serves files off disk, how TLS is handled, and which of the usual extras you want — and the tool emits two configs at the same time: an nginx server block and a Caddyfile that do the same job. Both panes have their own copy button, and the whole form is encoded in the URL so a config you built is a link you can paste into a ticket.
The toggles cover the things people actually forget: HTTP to HTTPS redirect, gzip, the four security headers worth setting unconditionally, per-IP rate limiting, WebSocket upgrade plumbing, and basic auth. Static and SPA modes differ in exactly one line — the SPA fallback — but that one line is the difference between deep links working and every refresh returning 404.
How it works
Everything is a pure function of the form state, evaluated in your browser. There is no template server, no account, and no request logged anywhere. Two builders run on every keystroke: one walks the nginx directive tree and one walks the Caddyfile.
The generators are opinionated where the two servers genuinely differ rather than
pretending they are interchangeable. In reverse-proxy mode the nginx output declares
an upstream block with keepalive 32 and sets the four forwarding headers by hand,
because ngx_http_proxy_module
does not forward the client address unless you tell it to. The Caddy equivalent is a
single reverse_proxy
line, since Caddy sets X-Forwarded-For and X-Forwarded-Proto on its own.
TLS is the other place the two diverge sharply. Picking Let’s Encrypt in nginx gives
you a port 80 server block that keeps /.well-known/acme-challenge/ reachable over
plain HTTP — a requirement of the HTTP-01 challenge in
RFC 8555 — plus explicit
ssl_certificate paths under /etc/letsencrypt/live/. The same choice in Caddy
produces a two-line global options block and nothing else, because
automatic HTTPS provisions the
certificate, renews it, and installs the redirect without configuration.
Directives that will not work where you paste them
Read the comments in the nginx pane before you reload. Two of the generated
directives are only legal in http{} scope, not inside a server{} block:
limit_req_zone from
ngx_http_limit_req_module,
and the map $http_upgrade $connection_upgrade block that the
documented WebSocket pattern
depends on. Drop them in a file under conf.d/ and keep the server block clean. If
you paste the file wholesale into sites-available/ you get
"limit_req_zone" directive is not allowed here and a failed reload.
Two features are also honestly unavailable in stock builds, and the tool says so
instead of emitting config that will not load. Brotli in nginx needs the
out-of-tree ngx_brotli module. Rate limiting in Caddy needs a third-party module
compiled in with xcaddy; the directive is emitted commented out so
caddy validate still passes. Basic auth in Caddy takes a bcrypt hash, not a
password — generate it with caddy hash-password and paste the result over the
placeholder.
When to reach for it
The obvious case is standing up a new vhost and not wanting to copy the last one
and miss a server_name. The more useful case is migration: if you are weighing a
move from nginx to Caddy, generating both halves of the same config side by side
shows you concretely how much of your nginx file is ceremony that Caddy handles for
you, and which parts (rate limiting, Brotli) you would actually lose.
It is also a decent teaching artifact. The SPA mode makes the try_files fallback
and the cache-control split between hashed assets and index.html visible in one
screen, which is easier to explain than prose.
Related tools
- HTTP header inspector to confirm the security headers you just added are actually on the wire.
- curl command builder for reproducing a request against the new vhost.
- TLS certificate inspector to check the chain and expiry after the first ACME issuance.
- Kubernetes YAML linter when the same app is behind an Ingress instead.
- DNS lookup to verify the A record and CAA policy before you request a certificate.
Frequently asked questions
Why does the nginx output put some directives outside the server block?+
limit_req_zone and the map used for WebSocket upgrades are only valid in http{} scope, not inside server{}. If you paste the whole file into sites-available/ without moving them, nginx fails to start with "limit_req_zone" directive is not allowed here. Put them in a file under conf.d/ instead.The Caddyfile is so much shorter. Am I missing something?+
Why is rate limiting commented out in the Caddyfile?+
rate_limit directive in the standard distribution. It comes from a third-party module you have to compile in with xcaddy. Rather than emit config that fails caddy validate, the tool leaves it commented with the plugin name.Does gzip cover Brotli too?+
gzip on is built in, but Brotli requires the out-of-tree ngx_brotli module, so it is emitted as a comment. Caddy's encode zstd gzip ships in the standard build; Zstandard and gzip cover essentially every client, and Brotli support in Caddy is compression-only for pre-compressed files.Will this config pass a TLS scanner?+
ssl_prefer_server_ciphers off lets the client choose, which is the current recommendation for TLS 1.3.Related tools
HTTP Header Inspector
Paste a URL, see the response headers with a plain-English explanation of each.
curl Command Builder
Visual builder for curl commands. Fill in method, headers, and body — copy the exact command.
TLS Certificate Inspector
Fetch a live certificate chain by hostname or paste a PEM. Decodes subject, SANs, validity, key and signature algorithms, fingerprints and embedded SCTs.