Version-control the shared Caddy edge proxy
The droplet's single Caddy container terminates TLS for every site and routes each host to its upstream over proxy_net. Until now its only copy lived on the server; capture compose.yaml and the Caddyfile here, with a README covering how to add a site and reload without downtime. ACME material is git-ignored.
This commit is contained in:
commit
438573ea7b
4 changed files with 117 additions and 0 deletions
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# ACME material and issued certs - private keys, never commit.
|
||||
letsencrypt/
|
||||
acme.json
|
||||
|
||||
# Caddy's data/config live in named Docker volumes on the droplet, not here.
|
||||
data/
|
||||
config/
|
||||
7
Caddyfile
Normal file
7
Caddyfile
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
personaledson.com.br, app.personaledson.com.br, api.personaledson.com.br, www.personaledson.com.br {
|
||||
reverse_proxy bigode-gateway-1:80
|
||||
}
|
||||
|
||||
www.nazareonline.com.br, nazareonline.com.br {
|
||||
reverse_proxy nazareonline-web-1:80
|
||||
}
|
||||
80
README.md
Normal file
80
README.md
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# central-proxy
|
||||
|
||||
The shared edge reverse proxy for the DigitalOcean droplet (`174.138.36.232`).
|
||||
A single **Caddy** container terminates TLS for every site on the box and routes
|
||||
each hostname to the right upstream container. It is the only thing published on
|
||||
ports 80 and 443; all the application stacks (bigode, nazareonline, ...) sit
|
||||
behind it on the external `proxy_net` Docker network and speak plain HTTP to it.
|
||||
|
||||
Caddy manages Let's Encrypt certificates automatically - it obtains and renews a
|
||||
cert for each hostname listed in the `Caddyfile` on first request. Issued certs
|
||||
and ACME account keys persist in the `caddy_data` Docker volume (mounted at
|
||||
`/data`), not in this repo.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
compose.yaml the Caddy service: publishes 80/443, joins proxy_net,
|
||||
bind-mounts the Caddyfile, persists certs in caddy_data
|
||||
Caddyfile one site block per app; each reverse_proxies to a container
|
||||
reachable by name on proxy_net
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- The external network exists: `docker network create proxy_net`.
|
||||
- Each upstream stack attaches its public-facing container to `proxy_net`, so
|
||||
Caddy can reach it by container name (e.g. `nazareonline-web-1:80`).
|
||||
- DNS A records for every hostname in the `Caddyfile` point at the droplet.
|
||||
|
||||
## Adding a site
|
||||
|
||||
Add a block to the `Caddyfile` naming the hostname(s) and the upstream:
|
||||
|
||||
```
|
||||
www.example.com, example.com {
|
||||
reverse_proxy example-web-1:80
|
||||
}
|
||||
```
|
||||
|
||||
The upstream container must be on `proxy_net`. Caddy forwards the original `Host`
|
||||
and sets `X-Forwarded-Proto: https`, so upstreams behind it can rebuild HTTPS
|
||||
URLs and do their own host canonicalisation.
|
||||
|
||||
Then reload without downtime (does not disturb the other sites):
|
||||
|
||||
```sh
|
||||
docker exec central-proxy-caddy-1 caddy reload --config /etc/caddy/Caddyfile
|
||||
```
|
||||
|
||||
Validate a change before reloading:
|
||||
|
||||
```sh
|
||||
docker run --rm -v "$PWD/Caddyfile":/etc/caddy/Caddyfile:ro caddy:2-alpine \
|
||||
caddy validate --config /etc/caddy/Caddyfile
|
||||
```
|
||||
|
||||
## Deploy
|
||||
|
||||
The compose stack lives at `/home/waldson/central-proxy` on the droplet. To
|
||||
apply a change, copy the edited `Caddyfile` up and reload:
|
||||
|
||||
```sh
|
||||
scp -i ~/.ssh/deploy_key ./Caddyfile waldson@174.138.36.232:/home/waldson/central-proxy/Caddyfile
|
||||
ssh -i ~/.ssh/deploy_key waldson@174.138.36.232 \
|
||||
'docker exec central-proxy-caddy-1 caddy reload --config /etc/caddy/Caddyfile'
|
||||
```
|
||||
|
||||
Bring the proxy up (or recreate it after a compose change) from that directory:
|
||||
|
||||
```sh
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- `letsencrypt/acme.json` is leftover state from an earlier Traefik-based proxy
|
||||
and is not used by Caddy. It is git-ignored (it contains private keys); it can
|
||||
be deleted from the droplet once you are sure nothing references it.
|
||||
- Never `docker volume rm caddy_data` - that discards every issued certificate
|
||||
and forces re-issuance, which can hit Let's Encrypt rate limits.
|
||||
23
compose.yaml
Normal file
23
compose.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
name: central-proxy
|
||||
|
||||
services:
|
||||
caddy:
|
||||
image: caddy:2-alpine
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
networks:
|
||||
- proxy_net
|
||||
|
||||
networks:
|
||||
proxy_net:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
caddy_data:
|
||||
caddy_config:
|
||||
Loading…
Add table
Add a link
Reference in a new issue