![Set Up a Reverse Proxy With Caddy](https://cdn.slatesource.com/e/3/a/e3a402bc-dafe-4977-abd5-202a49dacd58.jpg)

# Set Up a Reverse Proxy With Caddy

- [Made in Slatesource](https://slatesource.com/u/kairenner/set-up-a-reverse-proxy-with-caddy-999)
- By [KaiRenner](https://slatesource.com/u/KaiRenner)
- Science & Technology
- Created on Mar 23, 2026

## One Box, Many Services, One Port 443

Without a reverse proxy, every service on your Pi needs its own port: Nextcloud on 8080, Grafana on 3000, Vaultwarden on 8200. You tell people "go to http://192.168.1.50:8080" and they give you a look. With Caddy as a reverse proxy, every service gets its own subdomain — nextcloud.home.example.com, grafana.home.example.com — all reached over standard HTTPS port 443 with a real certificate. Caddy handles automatic certificate renewal through Let's Encrypt, and its configuration syntax is simple enough to read without a manual.

**One** Port 443

Add Caddy to Your Docker Compose Stack

Create a new directory for your Caddy service: mkdir -p ~/docker/caddy/config. Inside your main docker-compose.yml (or a new one for Caddy), add a caddy service using the caddy image. Mount your Caddyfile into /etc/caddy/Caddyfile inside the container, mo

Write the Caddyfile for Subdomain Routing

The Caddyfile format is a block per site. For each service, write a block starting with the subdomain — such as nextcloud.example.com — followed by curly braces containing a reverse\_proxy directive pointing to the container's service name and internal por

Configure Internal Docker Networking

Create a dedicated Docker network named proxy in your compose file. Attach Caddy to this network. Attach each application container (Nextcloud, Grafana, Vaultwarden) to the same proxy network. Remove any published ports from those application containers —

Understand Automatic HTTPS via ACME

When Caddy sees a public domain name in the Caddyfile, it automatically initiates the ACME challenge with Let's Encrypt to obtain a TLS certificate. For the HTTP-01 challenge, Let's Encrypt makes a request to your domain on port 80 — so your router must f

Create a dedicated Docker network named proxy for all reverse-proxied services and keep application containers off the default bridge network. The default bridge gives all containers on your host a path to each other, which is broader than necessary. A named network limits communication to only the containers you explicitly attach to it.

## What Comes Next

Caddy fetches TLS certificates by talking to DNS — your domain name must resolve to your server before Let's Encrypt will issue a cert. That means to understand what Caddy is actually doing, and to set up split-horizon DNS so your local services resolve correctly inside your home network, you need to understand how DNS actually works.

[

![Understand DNS for Self-Hosters](https://cdn.slatesource.com/d/c/d/dcd5d6b8-4a3e-4a61-83b8-497217827460.jpg)

Understand DNS for Self-HostersBy KaiRenner

](/u/kairenner/understand-dns-for-self-hosters-1010)

[The Caddyfile reference](https://caddyserver.com/docs/caddyfile?utm_source=slatesource)