Files
hermes-skills/skills/devops/infrastructure-automation/references/caddy-subdomain-routing.md
T

74 lines
2.7 KiB
Markdown

# Caddy Subdomain Routing Pattern
## When to Use Subdomains vs Path-Based Routing
**Subdomains** (`n8n.itpropartner.com`) are preferred when:
- The backend app uses absolute asset paths (`/assets/foo.js`, `/static/bar.css`)
- The app has its own SPA router that doesn't support base-path rewriting
- You need WebSocket support for real-time features
- The app redirects internally (signin flows, OAuth callbacks)
**Path-based** (`app1.itpropartner.com/n8n/`) only works when:
- The app supports `BASE_PATH` or equivalent configuration
- All internal asset references are relative or use the base path
- You've verified the SPA router handles the sub-path correctly
## Subdomain Caddyfile Pattern
```caddy
n8n.itpropartner.com {
reverse_proxy 127.0.0.1:5678 {
flush_interval -1
}
}
```
`flush_interval -1` enables WebSocket support — required for n8n's real-time editor.
## Let's Encrypt Pitfalls
### Rate Limit: Too Many Failed Authorizations
If DNS isn't pointing to the server when cert issuance is attempted, failed validations count against a 5-per-hour-per-domain rate limit. After 5 failures, Let's Encrypt blocks further attempts for 1 hour.
**Fix:** Ensure DNS A record resolves to the correct IP BEFORE adding the domain to Caddyfile. Caddy auto-requests certs on config load.
### Staging vs Production Certs
Caddy tries staging first, then production. A staging cert issuance success does NOT mean the production cert will work — they have separate rate limits.
### Retry After Rate Limit
Caddy auto-retries when the limit resets. Check with:
```bash
journalctl -u caddy --no-pager -n 20 | grep -E "cert|rateLimit|will retry"
```
## n8n-Specific Configuration
### Docker Volume Permissions
When migrating n8n Docker volumes between servers, the `n8n_data` volume must be owned by UID 1000 (the `node` user inside the container):
```bash
chown -R 1000:1000 /var/lib/docker/volumes/n8n_n8n_data/_data
```
Failure to do this causes `EACCES: permission denied, open '/home/node/.n8n/crash.journal'`.
### N8N_PROTOCOL Behind Reverse Proxy
Set `N8N_PROTOCOL=http` when behind Caddy — Caddy handles SSL termination. Setting it to `https` inside forces n8n to do its own SSL redirects, creating redirect loops.
### N8N_HOST
Must match the public domain — `n8n.itpropartner.com`. n8n uses this for OAuth callbacks and webhook URLs.
### Migration Steps
1. Stop old containers: `docker compose down`
2. Tar volumes: `tar czf n8n-data.tar.gz -C /var/lib/docker/volumes n8n_postgres_data n8n_n8n_data`
3. SCP to new server
4. Extract, create volumes, restore data
5. Fix permissions on `n8n_data` volume
6. Update `.env` with new `N8N_HOST` and `N8N_PROTOCOL=http`
7. `docker compose up -d`