Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,10 @@ ENV_PING_PASSWORD=

# --- SEO: SPA application directory
ENV_SPA_DIR=

# --- HTTP Early Hints (optional)
# Comma-separated Link header values used by Caddy to emit 103 Early Hints.
# Example preload directives for a built Vue app:
# </assets/index-sqsQjSaJ.js>; rel=modulepreload; as=script,
# </assets/index-CQed9K_I.css>; rel=preload; as=style
EARLY_HINTS_LINKS=
15 changes: 14 additions & 1 deletion caddy/Caddyfile.local
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,21 @@
respond 204
}

@early_hints {
method GET HEAD
expression {env.EARLY_HINTS_LINKS} != ""
}

# Reverse proxy all incoming requests to the 'api' service.
# - The service name 'api' is resolved by Docker's internal DNS to the correct container IP on the 'caddy_net' network.
# - The API container listens on port 8080 (from the ENV_HTTP_PORT).
reverse_proxy api:8080
reverse_proxy api:8080 {
handle_response @early_hints {
respond 103 {
header Link {env.EARLY_HINTS_LINKS}
}

copy_response
}
}
}
25 changes: 18 additions & 7 deletions caddy/Caddyfile.prod
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,25 @@ oullin.io {
}
}

# --- Default handler: proxy to web, preserving Host (ALL inside reverse_proxy)
handle {
reverse_proxy web:80 {
header_up Host {host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-For {remote}
@early_hints {
method GET HEAD
expression {env.EARLY_HINTS_LINKS} != ""
}

# --- Default handler: optional Early Hints before proxying to web
reverse_proxy web:80 {
handle_response @early_hints {
respond 103 {
header Link {env.EARLY_HINTS_LINKS}
}

copy_response
}

header_up Host {host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-For {remote}
}
}

Expand Down
13 changes: 13 additions & 0 deletions caddy/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,16 @@ header_down X-Debug-Username {http.request.header.X-API-Username}
header_down X-Debug-Key {http.request.header.X-API-Key}
header_down X-Debug-Signature {http.request.header.X-API-Signature}
```

### Early Hints

Set the `EARLY_HINTS_LINKS` environment variable to a comma-separated list of
[`Link` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link)
values (for example: `</assets/index-CQed9K_I.css>; rel=preload; as=style, </assets/index-sqsQjSaJ.js>; rel=modulepreload; as=script`).
When this variable is defined Caddy will emit an HTTP `103 Early Hints`
response for eligible GET and HEAD requests before proxying traffic, allowing
clients to start fetching the referenced assets while the upstream response is
prepared. The local and production Caddyfiles attach a `handle_response`
interceptor to `reverse_proxy` so the proxy can send the Early Hints response
and then `copy_response` from the upstream service without interrupting the
request flow.