Caddyfile reverse proxy: example and generator
Send visitors to an app on port 3000 and get HTTPS certificates automatically.
Caddy is a web server that gets and renews HTTPS certificates for you. A reverse proxy config is only a few lines: your domain, and the port your app listens on. Fill in both below, then follow the steps.
Create your config file
Type your own values. The file below updates as you type, and nothing you type leaves your browser.
example.com {
encode zstd gzip
reverse_proxy 127.0.0.1:3000
}How this setup works
Step-by-step setup
- Start your app so it listens on 127.0.0.1:3000.
- Install Caddy from caddyserver.com/docs/install.
- Save the config above as /etc/caddy/Caddyfile.
- Check it: caddy validate --config /etc/caddy/Caddyfile.
- Apply it: sudo systemctl reload caddy.
What the important lines mean
- example.com { ... } is the site block. Caddy turns on HTTPS for a real domain by itself.
- reverse_proxy sends traffic to 127.0.0.1:3000. WebSockets work without extra lines.
- encode compresses responses so pages load faster.
Common errors and how to fix them
- 502 Bad Gateway
- Caddy cannot reach your app. Check the app is running on port 3000.
- The certificate is not issued
- The domain must point to this server, and ports 80 and 443 must be open to the internet. Check sudo journalctl -u caddy for the reason.
- bind: address already in use
- Another program, often nginx or Apache, already uses port 80 or 443. Stop it or move it to another port.
Frequently asked questions
- Do I need certbot with Caddy?
- No. For a public domain that points to your server, Caddy requests and renews certificates on its own. Ports 80 and 443 must be reachable from the internet.
- Does Caddy support WebSockets?
- Yes. The reverse_proxy line handles WebSocket connections without extra settings.
- Can I use this on localhost?
- Yes. Use localhost as the domain. Caddy then uses its own local certificate, so your browser may ask you to trust it.
Free tools that help
- Common ports listSearch a list of common TCP and UDP port numbers: SSH 22, HTTP 80, HTTPS 443, MySQL 3306, PostgreSQL 5432 and more, with dev server ports.
Fix a problem with this setup
- CORS error on localhostFix "blocked by CORS policy" when your frontend on localhost calls an API: add the right headers on the server, or use a dev proxy.
- Node EADDRINUSEFix EADDRINUSE in Node, Express, Next.js and Vite: find the program using the port, stop it, or start on another port.
More server configs
- crontab examplesRun a script every minute, hour, day or week.
- systemd service fileRun your app in the background and start it automatically at boot.
- Apache virtual hostHost a website from a folder with Apache, with or without .htaccess.
- logrotate configKeep log files from filling your disk: rotate, compress and delete old logs on a schedule.
- fail2ban jail.localBan addresses that keep failing to log in. Choose ban time, retries and which services to protect.
- PM2 ecosystem.config.jsRun a Node.js app with PM2: restarts on crash, memory limit, cluster mode and start at boot.