Deployment guide

Deploy your applications with Caddy on a VPS

Deploy on a VPS Cloud →

Deployment7 min read

Deploy your applications with Caddy on a VPS

Caddy is a web server and reverse proxy written in Go whose signature is automatic HTTPS: it obtains and renews your TLS certificates with no configuration. On a VPS, a three-line Caddyfile replaces dozens of lines of Nginx plus Certbot, which makes it the fastest option for exposing an application over HTTPS.

Why choose Caddy as the front end on your VPS?

The historical complexity of a reverse proxy comes down to TLS: generating a certificate, configuring renewal, managing the HTTP→HTTPS redirection. Caddy removes all of that. As soon as you specify a domain name in the Caddyfile, it contacts Let's Encrypt (or ZeroSSL as a fallback), provisions the certificate, staples it (OCSP stapling) and renews it in the background. The configuration is readable, short, and hot-reloadable without service interruption.

Caddy's strengths in production

  • End-to-end automatic HTTPS: issuance, renewal and redirection without intervention
  • Minimalist Caddyfile: a block of a few lines per site, far shorter than an Nginx config
  • Built-in reverse proxy with health checks and load balancing to your containers or local ports
  • HTTP/2 and HTTP/3 (QUIC) enabled by default
  • Hot reload of the configuration (caddy reload) without interrupting connections
  • JSON administration API to drive the configuration dynamically

Prerequisites

Caddy is frugal: 1 vCPU and 512 MB to 1 GB of RAM are enough to serve several sites as a reverse proxy. You can choose between installing it as a system binary (systemd service) on Ubuntu/Debian, or running it in a Docker container. In both cases, you need a domain pointing to the VPS IP and ports 80, 443 (and 443/UDP for HTTP/3) open in your firewall.

Deploy Caddy as a reverse proxy

01

Install Caddy

On Ubuntu/Debian, add the official repository then apt install caddy. Caddy registers itself as a systemd service active at startup. Check: systemctl status caddy. In container mode, start from the caddy:latest image and mount a volume on /data to persist the certificates.

02

Point the DNS and open the ports

Create an A record app.yourdomain.com to the VPS IP. Open the necessary ports: ufw allow 80, ufw allow 443 and ufw allow 443/udp for HTTP/3. Port 80 is essential for Let's Encrypt's HTTP challenge.

03

Write the Caddyfile

Edit /etc/caddy/Caddyfile. To expose an application running locally on port 3000: app.yourdomain.com { reverse_proxy localhost:3000 }. That's all: Caddy deduces that HTTPS is needed because you specified a domain and triggers the certificate issuance.

04

Reload and check

Apply the configuration without downtime: caddy reload --config /etc/caddy/Caddyfile. Follow the certificate acquisition in the logs: journalctl -u caddy -f. On the first HTTPS call to your domain, the certificate is in place.

05

Add security headers and compression

Enrich the block with a header directive for HSTS and the anti-clickjacking headers, and enable encode gzip zstd for compression. Since the config is declarative, these additions stay readable and a simple caddy reload applies them.

To host several applications on the same VPS, simply list several site blocks in the same Caddyfile, each with its reverse_proxy. And for local development without a public domain, replace the domain name with :80 or use the tls internal directive: Caddy then generates a local CA and signs the certificate itself, handy for an internal pre-production environment.

The official documentation

For advanced configuration and options specific to the tool, refer to the official Caddy documentation. This guide covers going live on a VPS; the vendor's docs remain the reference for fine-tuning, major updates and specific use cases.

Put Caddy in front of your applications on a Cloud VPS

Deploy a ServOrbit Cloud VPS with the Deployment template: Caddy handles automatic HTTPS while you focus on your application.

Need help?

Browse our help center and FAQ, or write to our team — support in French, English and Arabic.