Caddy

On this page 7

Caddy is an open-source web server and reverse proxy written in Go whose defining feature is automatic HTTPS: it obtains, installs and renews TLS certificates for configured domains without separate tools. Among web servers in the servers domain, it sits alongside Nginx and Apache as a general-purpose choice for serving static files, proxying applications and running PHP sites through FastCGI.

Caddy is distributed as a single static binary with no external dependencies, configured either through the concise Caddyfile format or through a native JSON configuration that can be changed at runtime via an administrative API. It is released under the Apache 2.0 license.

How Caddy handles HTTPS automatically

Caddy handles HTTPS automatically by acting as its own ACME client. When a site block names a public domain, Caddy requests a certificate from an ACME certificate authority, by default a free public authority with a second one as a fallback, proves control of the domain and renews the certificate well before it expires, typically when about one third of its lifetime remains.

It also redirects HTTP to HTTPS by default, enables modern TLS versions and supports HTTP/2 and HTTP/3 over QUIC without extra settings. For internal names such as localhost, Caddy issues certificates from its own local certificate authority, which makes HTTPS available in development environments as well.

ChallengeRequirementTypical use
HTTP-01Port 80 reachable from the internetStandard public websites
TLS-ALPN-01Port 443 reachable from the internetServers where port 80 is closed
DNS-01API access to the DNS provider through a pluginWildcard certificates, internal servers
ACME challenge types used by Caddy

A feature called on-demand TLS goes further: Caddy obtains a certificate during the first TLS handshake for a hostname it has not seen before. This suits platforms that host customer domains, but it must be restricted with an approval endpoint to prevent abuse and rate limit exhaustion.

Configuration model and modules

Caddy’s configuration is natively JSON, and the Caddyfile is an adapter that converts a short human-friendly syntax into that JSON. A complete reverse proxy with HTTPS can be expressed in two or three lines, which is the main reason administrators adopt it.

MethodFormatBest suited for
CaddyfileDirective-based text fileManual configuration of most sites
JSON fileFull native structureGenerated or version-controlled configurations
Admin APIJSON over HTTP on localhost port 2019Changes at runtime without restart
Config adaptersOther formats translated to JSONIntegration with existing tooling
Ways to configure Caddy

Functionality is organized as modules compiled into the binary. Common directives include reverse_proxy, file_server, php_fastcgi, encode for compression and header for response headers. Extra modules, such as DNS provider plugins, are added by building a custom binary, usually with the xcaddy tool, because Caddy does not load modules dynamically.

Configuration reloads are graceful and atomic: a new configuration is validated first, and if it fails, the running one stays in place, so an error does not take the server offline.

Caddy compared with Nginx and Apache

Caddy, Nginx and Apache can all serve the same sites, but they differ in defaults, configuration style and ecosystem maturity. The choice usually depends on team experience and the amount of special tuning required.

AspectCaddyNginxApache
Automatic HTTPSBuilt inExternal ACME client neededExternal client or separate module
Configuration styleShort Caddyfile or JSONBlock-based configuration filesDirectives plus per-directory .htaccess
PHP integrationPHP-FPM through php_fastcgiPHP-FPM through FastCGIPHP-FPM or embedded module
Extension modelCompiled-in Go modulesCompiled or dynamic C modulesLarge set of loadable modules
Language and memory safetyGo, memory-safeCC
Ecosystem and tutorialsGrowingVery largeVery large
Comparison of common web servers

Nginx generally offers more fine-grained tuning and a larger body of operational knowledge for very high traffic. Caddy reduces configuration effort and certificate-related outages, which matters most for small teams running many domains.

Typical deployments and good practice

Caddy is most often deployed as an HTTPS front end for applications running on local ports or in containers, and as a straightforward server for static sites and PHP applications.

  • Persist the data directory, which stores certificates and keys; losing it in a container restart forces new issuance and can hit rate limits.
  • Open ports 80 and 443 to the internet unless DNS-01 challenges are used.
  • Keep the admin API bound to localhost or a protected socket, since it can change the full configuration.
  • Pin and rebuild custom binaries when using plugins, so updates do not silently drop a module.
  • Set explicit timeouts and request size limits for proxied applications that receive uploads.

Limitations to consider

Caddy’s convenience comes with a few constraints. Automatic certificate issuance depends on correct DNS and reachable ports, so a misconfigured record leads to repeated failed attempts, and certificate authorities enforce rate limits on failures.

There is no equivalent of Apache’s .htaccess, so applications that rely on per-directory rules, common in older PHP software, need their rewrite rules translated into the Caddyfile. Teams with deep existing Nginx automation may also find that migration costs outweigh the simplicity gains.

The simple explanation

Caddy is a program that delivers websites to visitors’ browsers. Its special talent is security. It sets up the padlock in the browser address bar by itself. Other web servers usually need a separate tool and some manual steps for that.

The padlock depends on a certificate that expires every few months. Caddy fetches and renews it in the background, so the site does not suddenly show a security warning because someone forgot a renewal. Its settings are also short and readable, which makes it popular with small teams.

How it is used in practice

A small software agency hosts twelve client web applications, each running in its own container on a single virtual server. Previously, an Nginx setup with a separate certificate tool caused two outages a year when renewals failed unnoticed. The agency replaces it with Caddy as the single front end, using a Caddyfile with one short site block per client domain and reverse_proxy to each container.

Caddy obtains all twelve certificates within minutes of the first start and renews them automatically. The data directory is stored on a persistent volume, so container updates do not trigger new issuance. Over the following year, the agency records no certificate-related outages, and adding a new client site takes one site block and a reload.