Add multi-site Caddy helpers and document usage
- add startup/shutdown scripts that render a Caddyfile from JSON config and run health checks - add Python utilities and a sample sites.json for declarative multi-site configuration - document the workflow and ignore generated Caddy state artifacts - normalize double-quote style across challenge workflow controllers, nodes, and tests
This commit is contained in:
parent
a99e716ad2
commit
6038fc25f5
26 changed files with 1018 additions and 168 deletions
99
docker/caddy/README.md
Normal file
99
docker/caddy/README.md
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
# Caddy Multi-Site Configuration
|
||||
|
||||
The Caddy helpers under `docker/` can now generate a single Caddyfile that serves multiple services. Instead of hard-coding upstreams in the shell script, each site to be exposed is described declaratively inside `docker/caddy/sites.json`.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
docker/
|
||||
startup-caddy.sh # Generates Caddyfile + runs caddy start --config ...
|
||||
shutdown-caddy.sh # Stops the running Caddy instance
|
||||
caddy/
|
||||
sites.json # Default site definitions (Dify + HackAPrompt example)
|
||||
state/ # Generated Caddyfile, logs, pid files
|
||||
```
|
||||
|
||||
Provide an alternative configuration file with `--config` or `CADDY_SITE_CONFIG` if you want a different set of sites.
|
||||
|
||||
```
|
||||
# Use a staging configuration
|
||||
./docker/startup-caddy.sh --config /path/to/staging-sites.json --regenerate
|
||||
```
|
||||
|
||||
## Config File Format
|
||||
|
||||
The configuration file is JSON with a top-level `sites` array. Each site object supports the keys below (all optional unless marked **required**):
|
||||
|
||||
| Key | Type | Description |
|
||||
| --- | ---- | ----------- |
|
||||
| `name` | string | Display name used in logs; defaults to `site`. |
|
||||
| `address` | string **required** | Caddy address such as `example.com` or `:8080`. |
|
||||
| `auto_https` | bool/string | Disable auto HTTPS when serving plain HTTP (default: `true`). |
|
||||
| `https_redirect` | bool/string | Emit an HTTP→HTTPS redirect block when a hostname is present. |
|
||||
| `acme_challenge` | bool/string | Adds a handler for `/.well-known/acme-challenge/*`. |
|
||||
| `headers` | object | Key/value pairs emitted inside a `header { ... }` block. |
|
||||
| `health_path` | string | Path exposed as a simple `respond` handler (default `/health`). |
|
||||
| `health_check` | object | `{ "url": "https://...", "skip": false }` controls post-start checks. |
|
||||
| `app_url` | string | Logged after startup for operator convenience. |
|
||||
| `log_file` | string | Custom log path; defaults to `$LOG_DIR/<name>-access.log`. |
|
||||
| `api_routes` | array | Each entry `{ "path": "/api/*", "upstream": "host:port" }` creates a `handle` block with `reverse_proxy`. |
|
||||
| `static_routes` | array | Each entry `{ "path": "/images/*", "root": "/var/www" }`; add `"browse": true` to enable directory listing. |
|
||||
| `frontend` | object | `{"type":"reverse_proxy","upstream":"host:port"}` or `{"type":"static","root":"/dir","try_files":[...]} `. |
|
||||
| `cache_static` | object | `{ "paths": ["*.js", ...], "header": "public, max-age=..." }`. |
|
||||
|
||||
All string values are expanded with `os.path.expandvars`, which means you can reference environment variables—`"${LOG_DIR}/dify-access.log"`, `"${DIFY_API_UPSTREAM:-127.0.0.1:5001}"`, etc.
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
{
|
||||
"sites": [
|
||||
{
|
||||
"name": "dify",
|
||||
"address": "${DIFY_ADDRESS:-:80}",
|
||||
"https_redirect": "${DIFY_REDIRECT:-false}",
|
||||
"api_routes": [
|
||||
{ "path": "/api/*", "upstream": "${DIFY_API_UPSTREAM:-127.0.0.1:5001}" }
|
||||
],
|
||||
"frontend": {
|
||||
"type": "reverse_proxy",
|
||||
"upstream": "${DIFY_FRONTEND_UPSTREAM:-127.0.0.1:3000}"
|
||||
},
|
||||
"health_check": {
|
||||
"url": "${DIFY_HEALTH_URL:-http://127.0.0.1/health}",
|
||||
"skip": "${DIFY_SKIP_HEALTHCHECK:-false}"
|
||||
},
|
||||
"app_url": "${DIFY_APP_URL:-http://127.0.0.1}"
|
||||
},
|
||||
{
|
||||
"name": "hackaprompt",
|
||||
"address": "${HACKAPROMPT_ADDRESS:-:8080}",
|
||||
"frontend": {
|
||||
"type": "static",
|
||||
"root": "${HACKAPROMPT_FRONTEND_ROOT:-/opt/hackaprompt-chat-viewer/frontend}",
|
||||
"try_files": ["{path}", "{path}/", "/index.html"]
|
||||
},
|
||||
"api_routes": [
|
||||
{ "path": "/api/*", "upstream": "${HACKAPROMPT_API_UPSTREAM:-127.0.0.1:5002}" }
|
||||
],
|
||||
"static_routes": [
|
||||
{ "path": "/images/*", "root": "${HACKAPROMPT_APP_ROOT:-/opt/hackaprompt-chat-viewer}" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Health Checks & Logs
|
||||
|
||||
After Caddy starts, the script runs a curl-based health check for each site unless `--skip-healthcheck` is passed globally or the site entry sets `"skip": true`. Each check waits up to 30 seconds.
|
||||
|
||||
Logs are written to `docker/caddy/state/logs/` by default. Adjust `log_file` per site if you want a different location.
|
||||
|
||||
## Stopping Caddy
|
||||
|
||||
```
|
||||
./docker/shutdown-caddy.sh
|
||||
```
|
||||
|
||||
The shutdown helper remains unchanged; it simply reads the PID file and stops the running Caddy instance.
|
||||
Loading…
Add table
Add a link
Reference in a new issue