Caddy

The only web server that obtains and renews TLS certificates automatically, with HTTP/1-2-3 support and zero dependency on external runtimes.

70.6Kstars
4.7Kforks
Apache License 2.0
Go

Caddy is a production-grade, extensible web server written in Go that makes HTTPS the default for every site it serves. From the moment you point a domain at it, Caddy handles certificate issuance via Let’s Encrypt or ZeroSSL, schedules renewals before expiry, and falls back to alternative issuers if the primary fails — all without a single manual step.

Beyond TLS automation, Caddy supports the full HTTP protocol stack: HTTP/1.1, HTTP/2, and HTTP/3 (QUIC) are all enabled out of the box. Its configuration model is uniquely flexible: the human-friendly Caddyfile is great for simple deployments, the native JSON API allows precise programmatic control, and config adapters let you feed in YAML, TOML, or even nginx config as input.

The server is built around a modular plugin architecture where almost every behavior — from route matching and middleware chaining to TLS certificate storage and load-balancing policies — is a swappable module. This means the core binary stays lean while a rich ecosystem of plugins covers use cases ranging from reverse proxying Docker containers to serving static files with automatic compression. The admin REST API allows zero-downtime config reloads and live monitoring without restarting the process.

What You Get

  • Automatic TLS certificate issuance and renewal via Let’s Encrypt, ZeroSSL, and a built-in internal CA for local/internal names
  • Full HTTP/1.1, HTTP/2, and HTTP/3 (QUIC) support enabled by default with no extra configuration
  • A human-friendly Caddyfile syntax alongside a native JSON config format and a live JSON API for zero-downtime reloads
  • A built-in reverse proxy with active/passive health checks, load balancing policies, retries, header manipulation, and FastCGI support
  • A static file server with directory browsing, compression (gzip, brotli, zstd), range requests, and ETag support
  • A modular plugin architecture that lets community or custom modules extend routing, TLS storage, certificate issuers, and middleware
  • An internal CA for automatically issuing trusted certificates to localhost and private IP addresses without extra tooling
  • Prometheus metrics, structured JSON logging, and distributed STEK (session ticket key) coordination for clustered deployments

Common Use Cases

  • Terminating HTTPS for self-hosted services without ever running certbot or managing cron jobs for renewal
  • Acting as a reverse proxy in front of Docker containers, Kubernetes pods, or bare-metal application servers with health-check-aware routing
  • Serving static websites with automatic HTTPS on a VPS, replacing heavier nginx or Apache setups
  • Providing an HTTPS gateway for local development environments by issuing certificates to localhost via the internal CA
  • Running as an API gateway that rewrites paths, strips headers, enforces authentication middleware, and routes to multiple upstream services
  • Replacing nginx in a home lab to simplify certificate management across many self-hosted applications with a single Caddyfile

Under The Hood

Architecture Caddy is built as a layered, modular platform rather than a conventional web server. At its core sits a context-scoped module lifecycle: every component — from TLS issuers and certificate storage backends to HTTP middleware and route matchers — implements a common Module interface and registers itself via init() calls. The server loads a single unified JSON config document, provisions each module through a Provision/Validate/Cleanup lifecycle, then swaps configurations atomically, enabling zero-downtime reloads where the old config’s modules are cleaned up only after the new ones are healthy. The HTTP server is organized as a pipeline of typed interfaces: RequestMatcherWithError, MiddlewareHandler, and Handler form a composable chain where each layer passes control to the next, with errors propagated down a separate error-handling chain rather than swallowed. The admin REST API and all runtime state live inside this same module system, so monitoring, config traversal, and even live certificate querying are first-class capabilities rather than bolted-on features.

Tech Stack Caddy is written entirely in Go and ships as a single statically linked binary with no runtime dependencies, not even libc. The HTTP transport layer uses Go’s standard net/http, extended with quic-go for HTTP/3 (QUIC) support. TLS automation is handled by the CertMagic library (also maintained by the Caddy author), which implements ACME (RFC 8555) via the acmez library and integrates with both Let’s Encrypt and ZeroSSL. The internal PKI module uses the step-ca (smallstep/certificates) library to operate a full CA for private names. Config adaptation is powered by adapters for TOML (BurntSushi/toml), JSON5, and nginx syntax. Request matching supports CEL expressions via google/cel-go for complex predicate evaluation. Observability is provided through Prometheus client_golang for metrics and zap for structured JSON logging. The cobra library handles the CLI surface.

Code Quality The codebase demonstrates comprehensive test coverage across extensive _test.go files at every layer, including fuzz targets for the replacer, listener parsing, and frontmatter parsing. Error handling follows Go idioms strictly: errors are typed (HandlerError wraps HTTP status codes), returned up the call stack rather than logged-and-ignored, and the middleware chain propagates them to a dedicated error-handling route. The module interface contract is enforced at compile time through interface assertions in init() blocks. CI runs the full test matrix on Linux, macOS, and Windows against the latest Go release, supplemented by golangci-lint with a project-specific .golangci.yml. Inline documentation is abundant — every exported type and field carries godoc comments that power the automatically generated JSON schema documentation on the Caddy website.

What Makes It Unique Caddy’s most distinctive technical contribution is treating HTTPS not as an opt-in feature but as the invariant default, implemented through deep integration with ACME at the application level rather than as a sidecar process. The internal CA — which issues and renews certificates for localhost and RFC 1918 addresses that public CAs cannot reach — is a capability no comparable open-source web server provides out of the box. The live JSON API for atomic config replacement without process restart, combined with a config adapter system that can translate nginx syntax into Caddy’s native format, makes migration and automation significantly lower-friction than alternatives. The plugin system is architecturally unusual in that plugins extend the config schema itself: adding a new module makes new JSON keys appear in the documented config tree automatically, rather than requiring separate plugin documentation.

Self-Hosting

Caddy is released under the Apache License 2.0, one of the most permissive open-source licenses available. You can use it in commercial products, modify the source, distribute binaries, and combine it with proprietary software without any copyleft obligations. The only requirements are preserving the license notice and attributing the original authors. For self-hosters, this means there are no runtime license checks, no feature gating, and no obligation to publish modifications.

Running Caddy yourself means taking full ownership of the server process, its TLS storage (which holds private keys and certificates), and the machines it runs on. The operational footprint is deliberately minimal — Caddy ships as a single static binary with no libc dependency, no runtime environment, and no external services required. Certificate storage defaults to the local filesystem, but can be pointed at any S3-compatible object store or a custom storage module. For clustered or high-availability deployments, you are responsible for sharing TLS state across instances, coordinating ACME challenges (Caddy supports this natively via its distributed STEK and certificate synchronization features), and setting up a load balancer in front of multiple Caddy nodes.

There is no official Caddy Cloud or hosted version. Commercial support is available through Ardan Labs as a third-party arrangement, and the project’s creator accepts sponsorships that fund ongoing development. Compared to managed alternatives like Caddy’s sister project or cloud-native load balancers (AWS ALB, Cloudflare, etc.), self-hosting means you handle uptime, capacity planning, incident response, and certificate emergency recovery yourself. What you gain is complete control, no per-request pricing, and the ability to serve internal hostnames that public CAs cannot issue certificates for — which is a meaningful advantage in private network and air-gapped environments.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack

No spam. Unsubscribe anytime.

Join 750+ subscribers
No spam. Unsubscribe anytime.

Search