Caddy HTTPS reverse proxy: a practical setup guide
Put an existing web app behind Caddy HTTPS. Check DNS, configure the reverse proxy, validate changes, and troubleshoot common failures.

A reverse proxy gives your application a public HTTPS address while the app listens on a private local port. This guide uses Caddy 2 on a Linux host and an existing application listening at 127.0.0.1:3000.
It assumes Caddy is already installed as a system service using the instructions for your distribution. It also assumes you control the domain's DNS. The examples use app.example.com; replace it with your actual hostname before running commands.
Check the application first
Test locally on the server:
curl -I http://127.0.0.1:3000
If the connection is refused, fix the app's process or port binding before changing DNS. If it returns a server error, inspect the app logs. Adding a reverse proxy will not repair a failing application.
Decide which hostname is canonical. If the app expects an external URL in its environment configuration, set it to the intended HTTPS address. This often affects login callbacks, password-reset links, and redirects.
Point DNS at the server
Create the appropriate DNS record for your hostname. An A record points to an IPv4 address; only publish an AAAA record when IPv6 is configured and reaches the same service. Remove stale records that send some visitors elsewhere.
For standard public certificate issuance, make ports 80 and 443 reachable through both your provider's network controls and the host firewall. Check that another web server is not already using those ports. DNS proxy services add another layer; confirm their configuration separately.
Caddy's automatic HTTPS documentation describes certificate requirements and exceptions. Do not apply public-domain assumptions to a private hostname without checking the relevant certificate method.
Add a small Caddyfile
For a host-based installation, edit the service's Caddyfile, commonly /etc/caddy/Caddyfile:
app.example.com {
reverse_proxy 127.0.0.1:3000
}
This configuration keeps the proxy easy to inspect. Avoid adding caching or complex rewrites before the basic request path works. The reverse_proxy reference covers advanced upstream and header settings.
Validate the file before reloading the running service:
sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
sudo systemctl reload caddy
sudo systemctl status caddy --no-pager
curl -I https://app.example.com
If validation fails, correct the reported file and line rather than restarting repeatedly. If certificate issuance fails, inspect DNS and reachability before changing application code.
Test the routes your customers use
Open the site from another network. Check an ordinary page, a deep URL, static assets, a login redirect, and a form submission. Confirm that generated links use HTTPS and that a browser refresh on a deep route works.
A 502 response usually means the proxy cannot successfully reach its upstream. Check whether the app is running and whether its port matches the Caddyfile. Redirect loops can indicate mismatched external URL or trusted-proxy settings in the application. Trust forwarding headers only from infrastructure you control.
Keep a copy of the working Caddyfile with your deployment documentation. For the application side, see our Docker Compose checklist. For help bringing the whole website live, explore web development.
