feat: add recommended Caddyfile and update usage guide for production configuration
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
## Pre-cutover
|
## Pre-cutover
|
||||||
- [ ] `nginx -T` snapshot captured (`output/nginx-full.conf`)
|
- [ ] `nginx -T` snapshot captured (`output/nginx-full.conf`)
|
||||||
- [ ] Generated Caddyfile reviewed
|
- [ ] Generated Caddyfile reviewed
|
||||||
|
- [ ] `Caddyfile.recommended` reviewed/adapted for your domains
|
||||||
- [ ] `conversion-warnings.txt` reviewed and resolved for canary site
|
- [ ] `conversion-warnings.txt` reviewed and resolved for canary site
|
||||||
- [ ] `validate_caddy.sh` passes
|
- [ ] `validate_caddy.sh` passes
|
||||||
- [ ] DNS TTL lowered for canary domain
|
- [ ] DNS TTL lowered for canary domain
|
||||||
|
|||||||
130
setup/nginx-to-caddy/Caddyfile.recommended
Normal file
130
setup/nginx-to-caddy/Caddyfile.recommended
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
# Recommended Caddy baseline for the current homelab reverse-proxy estate.
|
||||||
|
# Source upstreams were derived from setup/nginx-to-caddy/oldconfig/*.conf.
|
||||||
|
#
|
||||||
|
# If your public suffix changes (for example sintheus.com -> privacyindesign.com),
|
||||||
|
# update the hostnames below before deployment.
|
||||||
|
{
|
||||||
|
# DNS-01 certificates through Cloudflare.
|
||||||
|
# Requires CF_API_TOKEN in Caddy runtime environment.
|
||||||
|
acme_dns cloudflare {env.CF_API_TOKEN}
|
||||||
|
|
||||||
|
# Trust private-range proxy hops in LAN environments.
|
||||||
|
servers {
|
||||||
|
trusted_proxies static private_ranges
|
||||||
|
protocols h1 h2 h3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(common_security) {
|
||||||
|
encode zstd gzip
|
||||||
|
|
||||||
|
header {
|
||||||
|
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||||
|
X-Content-Type-Options "nosniff"
|
||||||
|
X-Frame-Options "SAMEORIGIN"
|
||||||
|
Referrer-Policy "strict-origin-when-cross-origin"
|
||||||
|
-Server
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(proxy_headers) {
|
||||||
|
# Keep Nginx parity for backends that consume Host and X-Real-IP.
|
||||||
|
header_up Host {host}
|
||||||
|
header_up X-Real-IP {remote_host}
|
||||||
|
}
|
||||||
|
|
||||||
|
(proxy_streaming) {
|
||||||
|
import proxy_headers
|
||||||
|
# Flush immediately for streaming/log-tail/websocket-heavy UIs.
|
||||||
|
flush_interval -1
|
||||||
|
}
|
||||||
|
|
||||||
|
ai.sintheus.com {
|
||||||
|
import common_security
|
||||||
|
|
||||||
|
request_body {
|
||||||
|
max_size 50MB
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse_proxy http://192.168.1.82:8181 {
|
||||||
|
import proxy_streaming
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
photos.sintheus.com {
|
||||||
|
import common_security
|
||||||
|
|
||||||
|
request_body {
|
||||||
|
max_size 50GB
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse_proxy http://192.168.1.222:2283 {
|
||||||
|
import proxy_headers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fin.sintheus.com {
|
||||||
|
import common_security
|
||||||
|
|
||||||
|
reverse_proxy http://192.168.1.233:8096 {
|
||||||
|
import proxy_streaming
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
disk.sintheus.com {
|
||||||
|
import common_security
|
||||||
|
|
||||||
|
request_body {
|
||||||
|
max_size 20GB
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse_proxy http://192.168.1.52:80 {
|
||||||
|
import proxy_headers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pi.sintheus.com {
|
||||||
|
import common_security
|
||||||
|
|
||||||
|
reverse_proxy http://192.168.1.4:80 {
|
||||||
|
import proxy_headers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plex.sintheus.com {
|
||||||
|
import common_security
|
||||||
|
|
||||||
|
reverse_proxy http://192.168.1.111:32400 {
|
||||||
|
import proxy_streaming
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sync.sintheus.com {
|
||||||
|
import common_security
|
||||||
|
|
||||||
|
reverse_proxy http://192.168.1.119:8384 {
|
||||||
|
import proxy_headers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
syno.sintheus.com {
|
||||||
|
import common_security
|
||||||
|
|
||||||
|
reverse_proxy https://100.108.182.16:5001 {
|
||||||
|
import proxy_headers
|
||||||
|
transport http {
|
||||||
|
tls_insecure_skip_verify
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tower.sintheus.com {
|
||||||
|
import common_security
|
||||||
|
|
||||||
|
reverse_proxy https://192.168.1.82:443 {
|
||||||
|
import proxy_headers
|
||||||
|
transport http {
|
||||||
|
tls_insecure_skip_verify
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,8 @@ This module is intentionally conservative:
|
|||||||
- SSH into a host and collect `nginx -T`, `/etc/nginx` tarball, and a quick inventory summary.
|
- SSH into a host and collect `nginx -T`, `/etc/nginx` tarball, and a quick inventory summary.
|
||||||
- `nginx_to_caddy.sh`
|
- `nginx_to_caddy.sh`
|
||||||
- Convert basic Nginx server blocks into a generated Caddyfile.
|
- Convert basic Nginx server blocks into a generated Caddyfile.
|
||||||
|
- `Caddyfile.recommended`
|
||||||
|
- Hardened baseline config (security headers, sensible body limits, streaming behavior).
|
||||||
- `validate_caddy.sh`
|
- `validate_caddy.sh`
|
||||||
- Run `caddy fmt`, `caddy adapt`, and `caddy validate` on the generated Caddyfile.
|
- Run `caddy fmt`, `caddy adapt`, and `caddy validate` on the generated Caddyfile.
|
||||||
|
|
||||||
@@ -24,6 +26,7 @@ cd setup/nginx-to-caddy
|
|||||||
./extract_nginx_inventory.sh --host=<host> --user=<user> --port=22 --yes
|
./extract_nginx_inventory.sh --host=<host> --user=<user> --port=22 --yes
|
||||||
./nginx_to_caddy.sh --input=./output/nginx-full.conf --output=./output/Caddyfile.generated --tls-mode=cloudflare --yes
|
./nginx_to_caddy.sh --input=./output/nginx-full.conf --output=./output/Caddyfile.generated --tls-mode=cloudflare --yes
|
||||||
./validate_caddy.sh --config=./output/Caddyfile.generated --docker
|
./validate_caddy.sh --config=./output/Caddyfile.generated --docker
|
||||||
|
./validate_caddy.sh --config=./Caddyfile.recommended --docker
|
||||||
```
|
```
|
||||||
|
|
||||||
## Conversion Scope
|
## Conversion Scope
|
||||||
|
|||||||
@@ -51,7 +51,23 @@ If local `caddy` is installed:
|
|||||||
./validate_caddy.sh --config=./output/Caddyfile.generated
|
./validate_caddy.sh --config=./output/Caddyfile.generated
|
||||||
```
|
```
|
||||||
|
|
||||||
## 4) Canary migration (recommended)
|
## 4) Use the recommended baseline
|
||||||
|
|
||||||
|
This toolkit now includes a hardened baseline at:
|
||||||
|
- `setup/nginx-to-caddy/Caddyfile.recommended`
|
||||||
|
|
||||||
|
Use it when you want a production-style config instead of a raw 1:1 conversion.
|
||||||
|
You can either:
|
||||||
|
1. use it directly (if hostnames/upstreams already match your environment), or
|
||||||
|
2. copy its common snippets and service patterns into your live Caddyfile.
|
||||||
|
|
||||||
|
Validate it before deployment:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./validate_caddy.sh --config=./Caddyfile.recommended --docker
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5) Canary migration (recommended)
|
||||||
|
|
||||||
Migrate one low-risk subdomain first:
|
Migrate one low-risk subdomain first:
|
||||||
1. Copy only one site block from generated Caddyfile to your live Caddy config.
|
1. Copy only one site block from generated Caddyfile to your live Caddy config.
|
||||||
@@ -62,7 +78,7 @@ Migrate one low-risk subdomain first:
|
|||||||
- API/websocket calls work
|
- API/websocket calls work
|
||||||
4. Keep Nginx serving all other subdomains.
|
4. Keep Nginx serving all other subdomains.
|
||||||
|
|
||||||
## 5) Full migration after canary success
|
## 6) Full migration after canary success
|
||||||
|
|
||||||
When the canary is stable:
|
When the canary is stable:
|
||||||
1. Add remaining site blocks.
|
1. Add remaining site blocks.
|
||||||
@@ -70,14 +86,14 @@ When the canary is stable:
|
|||||||
3. Keep Nginx config snapshots for rollback.
|
3. Keep Nginx config snapshots for rollback.
|
||||||
4. Decommission Nginx only after monitoring period.
|
4. Decommission Nginx only after monitoring period.
|
||||||
|
|
||||||
## 6) Rollback plan
|
## 7) Rollback plan
|
||||||
|
|
||||||
If a site fails after cutover:
|
If a site fails after cutover:
|
||||||
1. Repoint affected DNS entry back to Nginx endpoint.
|
1. Repoint affected DNS entry back to Nginx endpoint.
|
||||||
2. Restore previous Nginx server block.
|
2. Restore previous Nginx server block.
|
||||||
3. Investigate conversion warnings for that block.
|
3. Investigate conversion warnings for that block.
|
||||||
|
|
||||||
## 7) Domain/TLS note for your current setup
|
## 8) Domain/TLS note for your current setup
|
||||||
|
|
||||||
You confirmed the domain is `privacyindesign.com`.
|
You confirmed the domain is `privacyindesign.com`.
|
||||||
|
|
||||||
@@ -86,7 +102,7 @@ If you use `TLS_MODE=cloudflare` with Caddy, ensure:
|
|||||||
- Cloudflare token has DNS edit on the same zone.
|
- Cloudflare token has DNS edit on the same zone.
|
||||||
- DNS records point to the Caddy ingress path you intend (direct or via edge proxy).
|
- DNS records point to the Caddy ingress path you intend (direct or via edge proxy).
|
||||||
|
|
||||||
## 8) Suggested next step for Phase 8
|
## 9) Suggested next step for Phase 8
|
||||||
|
|
||||||
Given your current repo config:
|
Given your current repo config:
|
||||||
- keep Phase 8 Caddy focused on `source.privacyindesign.com`
|
- keep Phase 8 Caddy focused on `source.privacyindesign.com`
|
||||||
|
|||||||
@@ -49,35 +49,41 @@ fi
|
|||||||
|
|
||||||
CONFIG_FILE="$(cd "$(dirname "$CONFIG_FILE")" && pwd)/$(basename "$CONFIG_FILE")"
|
CONFIG_FILE="$(cd "$(dirname "$CONFIG_FILE")" && pwd)/$(basename "$CONFIG_FILE")"
|
||||||
|
|
||||||
|
docker_env_args=()
|
||||||
|
|
||||||
if [[ "$USE_DOCKER" == "true" ]]; then
|
if [[ "$USE_DOCKER" == "true" ]]; then
|
||||||
require_cmd docker
|
require_cmd docker
|
||||||
docker_env_args=()
|
|
||||||
if [[ -n "${CF_API_TOKEN:-}" ]]; then
|
if [[ -n "${CF_API_TOKEN:-}" ]]; then
|
||||||
docker_env_args+=( -e "CF_API_TOKEN=${CF_API_TOKEN}" )
|
docker_env_args+=( -e "CF_API_TOKEN=${CF_API_TOKEN}" )
|
||||||
elif [[ -n "${CLOUDFLARE_API_TOKEN:-}" ]]; then
|
elif [[ -n "${CLOUDFLARE_API_TOKEN:-}" ]]; then
|
||||||
docker_env_args+=( -e "CF_API_TOKEN=${CLOUDFLARE_API_TOKEN}" )
|
docker_env_args+=( -e "CF_API_TOKEN=${CLOUDFLARE_API_TOKEN}" )
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
run_docker_caddy() {
|
||||||
|
if [[ "${#docker_env_args[@]}" -gt 0 ]]; then
|
||||||
|
docker run --rm "${docker_env_args[@]}" "$@"
|
||||||
|
else
|
||||||
|
docker run --rm "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
if [[ "$FORMAT_FILE" == "true" ]]; then
|
if [[ "$FORMAT_FILE" == "true" ]]; then
|
||||||
log_info "Formatting Caddyfile with Docker..."
|
log_info "Formatting Caddyfile with Docker..."
|
||||||
docker run --rm \
|
run_docker_caddy \
|
||||||
"${docker_env_args[@]}" \
|
|
||||||
-v "$CONFIG_FILE:/etc/caddy/Caddyfile" \
|
-v "$CONFIG_FILE:/etc/caddy/Caddyfile" \
|
||||||
"$CADDY_IMAGE" caddy fmt --overwrite /etc/caddy/Caddyfile
|
"$CADDY_IMAGE" caddy fmt --overwrite /etc/caddy/Caddyfile
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$DO_ADAPT" == "true" ]]; then
|
if [[ "$DO_ADAPT" == "true" ]]; then
|
||||||
log_info "Adapting Caddyfile (Docker)..."
|
log_info "Adapting Caddyfile (Docker)..."
|
||||||
docker run --rm \
|
run_docker_caddy \
|
||||||
"${docker_env_args[@]}" \
|
|
||||||
-v "$CONFIG_FILE:/etc/caddy/Caddyfile:ro" \
|
-v "$CONFIG_FILE:/etc/caddy/Caddyfile:ro" \
|
||||||
"$CADDY_IMAGE" caddy adapt --config /etc/caddy/Caddyfile --adapter caddyfile >/dev/null
|
"$CADDY_IMAGE" caddy adapt --config /etc/caddy/Caddyfile --adapter caddyfile >/dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$DO_VALIDATE" == "true" ]]; then
|
if [[ "$DO_VALIDATE" == "true" ]]; then
|
||||||
log_info "Validating Caddyfile (Docker)..."
|
log_info "Validating Caddyfile (Docker)..."
|
||||||
docker run --rm \
|
run_docker_caddy \
|
||||||
"${docker_env_args[@]}" \
|
|
||||||
-v "$CONFIG_FILE:/etc/caddy/Caddyfile:ro" \
|
-v "$CONFIG_FILE:/etc/caddy/Caddyfile:ro" \
|
||||||
"$CADDY_IMAGE" caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
|
"$CADDY_IMAGE" caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user