74 lines
2.7 KiB
Markdown
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`
|