499 lines
8.6 KiB
Caddyfile
499 lines
8.6 KiB
Caddyfile
# Global options
|
|
{
|
|
email admin@bronhouder.nl
|
|
|
|
servers {
|
|
timeouts {
|
|
read_body 30s
|
|
read_header 10s
|
|
write 900s
|
|
idle 120s
|
|
}
|
|
max_header_size 16KB
|
|
}
|
|
|
|
# Structured JSON logging for all requests
|
|
log {
|
|
output file /var/log/caddy/access.log {
|
|
roll_size 100mb
|
|
roll_keep 5
|
|
roll_keep_for 168h
|
|
}
|
|
format json
|
|
level INFO
|
|
}
|
|
}
|
|
|
|
(sparql_protection) {
|
|
request_body {
|
|
max_size 1MB
|
|
}
|
|
header X-Query-Timeout "60s"
|
|
}
|
|
|
|
(static_files) {
|
|
root * /var/www/glam-frontend
|
|
|
|
# CRITICAL FIX: Handle /assets/* separately - return 404 if not found
|
|
# This prevents SPA fallback from serving index.html for missing JS chunks
|
|
# which would cause "error loading dynamically imported module" errors
|
|
@assets {
|
|
path /assets/*
|
|
}
|
|
handle @assets {
|
|
# Check if file exists
|
|
@assets_exist file {path}
|
|
|
|
# Existing assets get long cache (they have content hashes in filenames)
|
|
route @assets_exist {
|
|
header Cache-Control "public, max-age=31536000, immutable"
|
|
file_server {
|
|
precompressed gzip br
|
|
}
|
|
}
|
|
|
|
# Missing assets return 404 with no-cache (browser should retry on refresh)
|
|
@assets_missing not file {path}
|
|
route @assets_missing {
|
|
header Cache-Control "no-cache, no-store, must-revalidate"
|
|
respond "Not Found" 404
|
|
}
|
|
}
|
|
|
|
# For all other paths: SPA behavior with try_files
|
|
handle {
|
|
# index.html should never be cached
|
|
@index {
|
|
path /
|
|
}
|
|
header @index Cache-Control "no-cache, no-store, must-revalidate"
|
|
|
|
# All HTML responses (including SPA fallback) should not be cached
|
|
header Content-Type text/html* Cache-Control "no-cache, no-store, must-revalidate"
|
|
|
|
try_files {path} /index.html
|
|
file_server {
|
|
precompressed gzip br
|
|
}
|
|
}
|
|
}
|
|
|
|
(archief_static_files) {
|
|
root * /var/www/archief-assistent
|
|
|
|
# Handle /assets/* separately - return 404 if not found
|
|
@assets {
|
|
path /assets/*
|
|
}
|
|
handle @assets {
|
|
@assets_exist file {path}
|
|
route @assets_exist {
|
|
header Cache-Control "public, max-age=31536000, immutable"
|
|
file_server {
|
|
precompressed gzip br
|
|
}
|
|
}
|
|
@assets_missing not file {path}
|
|
route @assets_missing {
|
|
header Cache-Control "no-cache, no-store, must-revalidate"
|
|
respond "Not Found" 404
|
|
}
|
|
}
|
|
|
|
# For all other paths: SPA behavior with try_files
|
|
handle {
|
|
@index {
|
|
path /
|
|
}
|
|
header @index Cache-Control "no-cache, no-store, must-revalidate"
|
|
header Content-Type text/html* Cache-Control "no-cache, no-store, must-revalidate"
|
|
try_files {path} /index.html
|
|
file_server {
|
|
precompressed gzip br
|
|
}
|
|
}
|
|
}
|
|
|
|
:80 {
|
|
handle /health {
|
|
respond "OK" 200
|
|
}
|
|
|
|
handle /ducklake/* {
|
|
uri strip_prefix /ducklake
|
|
reverse_proxy 127.0.0.1:8765 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /api/postgres/* {
|
|
uri strip_prefix /api/postgres
|
|
reverse_proxy 127.0.0.1:8001 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /api/geo/* {
|
|
uri strip_prefix /api/geo
|
|
reverse_proxy 127.0.0.1:8002 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /api/cache/* {
|
|
uri strip_prefix /api
|
|
reverse_proxy 127.0.0.1:8090 {
|
|
transport http {
|
|
read_timeout 60s
|
|
write_timeout 60s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /api/typedb/* {
|
|
uri strip_prefix /api/typedb
|
|
reverse_proxy 127.0.0.1:8003 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /api/sync/* {
|
|
reverse_proxy 127.0.0.1:8766 {
|
|
transport http {
|
|
read_timeout 900s
|
|
write_timeout 900s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /api/* {
|
|
reverse_proxy 127.0.0.1:8000 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
@sparqlQuery {
|
|
path /query
|
|
}
|
|
handle @sparqlQuery {
|
|
import sparql_protection
|
|
reverse_proxy 127.0.0.1:7878 {
|
|
transport http {
|
|
read_timeout 60s
|
|
write_timeout 60s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /sparql/* {
|
|
import sparql_protection
|
|
uri strip_prefix /sparql
|
|
reverse_proxy 127.0.0.1:7878 {
|
|
transport http {
|
|
read_timeout 60s
|
|
write_timeout 60s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /store* {
|
|
import sparql_protection
|
|
reverse_proxy 127.0.0.1:7878 {
|
|
transport http {
|
|
read_timeout 60s
|
|
write_timeout 60s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /update* {
|
|
import sparql_protection
|
|
reverse_proxy 127.0.0.1:7878 {
|
|
transport http {
|
|
read_timeout 60s
|
|
write_timeout 60s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /qdrant/* {
|
|
uri strip_prefix /qdrant
|
|
reverse_proxy 127.0.0.1:6333 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle {
|
|
import static_files
|
|
}
|
|
}
|
|
|
|
bronhouder.nl, www.bronhouder.nl {
|
|
# Site-specific logging for chunk load monitoring
|
|
log {
|
|
output file /var/log/caddy/bronhouder.log {
|
|
roll_size 50mb
|
|
roll_keep 3
|
|
roll_keep_for 72h
|
|
}
|
|
format json
|
|
level INFO
|
|
}
|
|
|
|
handle /health {
|
|
respond "OK" 200
|
|
}
|
|
|
|
handle /ducklake/* {
|
|
uri strip_prefix /ducklake
|
|
reverse_proxy 127.0.0.1:8765 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /api/postgres/* {
|
|
uri strip_prefix /api/postgres
|
|
reverse_proxy 127.0.0.1:8001 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /api/geo/* {
|
|
uri strip_prefix /api/geo
|
|
reverse_proxy 127.0.0.1:8002 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /api/cache/* {
|
|
uri strip_prefix /api
|
|
reverse_proxy 127.0.0.1:8090 {
|
|
transport http {
|
|
read_timeout 60s
|
|
write_timeout 60s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /api/typedb/* {
|
|
uri strip_prefix /api/typedb
|
|
reverse_proxy 127.0.0.1:8003 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /api/sync/* {
|
|
reverse_proxy 127.0.0.1:8766 {
|
|
transport http {
|
|
read_timeout 900s
|
|
write_timeout 900s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /api/* {
|
|
reverse_proxy 127.0.0.1:8000 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
@sparqlQuery {
|
|
path /query
|
|
}
|
|
handle @sparqlQuery {
|
|
import sparql_protection
|
|
reverse_proxy 127.0.0.1:7878 {
|
|
transport http {
|
|
read_timeout 60s
|
|
write_timeout 60s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /sparql/* {
|
|
import sparql_protection
|
|
uri strip_prefix /sparql
|
|
reverse_proxy 127.0.0.1:7878 {
|
|
transport http {
|
|
read_timeout 60s
|
|
write_timeout 60s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /store* {
|
|
import sparql_protection
|
|
reverse_proxy 127.0.0.1:7878 {
|
|
transport http {
|
|
read_timeout 60s
|
|
write_timeout 60s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /update* {
|
|
import sparql_protection
|
|
reverse_proxy 127.0.0.1:7878 {
|
|
transport http {
|
|
read_timeout 60s
|
|
write_timeout 60s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle /qdrant/* {
|
|
uri strip_prefix /qdrant
|
|
reverse_proxy 127.0.0.1:6333 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
handle {
|
|
import static_files
|
|
}
|
|
}
|
|
|
|
sparql.bronhouder.nl {
|
|
import sparql_protection
|
|
reverse_proxy 127.0.0.1:7878 {
|
|
transport http {
|
|
read_timeout 60s
|
|
write_timeout 60s
|
|
}
|
|
}
|
|
}
|
|
|
|
# ============================================================================
|
|
# ARCHIEF.SUPPORT - ArchiefAssistent (National Archives Services)
|
|
# ============================================================================
|
|
archief.support, www.archief.support {
|
|
# Site-specific logging
|
|
log {
|
|
output file /var/log/caddy/archief.log {
|
|
roll_size 50mb
|
|
roll_keep 3
|
|
roll_keep_for 72h
|
|
}
|
|
format json
|
|
level INFO
|
|
}
|
|
|
|
# Health check endpoint
|
|
handle /health {
|
|
respond "OK" 200
|
|
}
|
|
|
|
# Authentication API - proxied to de Aa auth backend (port 8080)
|
|
handle /auth/* {
|
|
reverse_proxy 127.0.0.1:8080 {
|
|
transport http {
|
|
read_timeout 30s
|
|
write_timeout 30s
|
|
}
|
|
}
|
|
}
|
|
|
|
# DSPy RAG API - proxied to RAG backend (port 8010)
|
|
handle /api/dspy/* {
|
|
uri strip_prefix /api/dspy
|
|
reverse_proxy 127.0.0.1:8010 {
|
|
transport http {
|
|
read_timeout 180s
|
|
write_timeout 180s
|
|
}
|
|
}
|
|
}
|
|
|
|
# RAG API endpoints - direct access to RAG backend
|
|
handle /api/rag/* {
|
|
reverse_proxy 127.0.0.1:8010 {
|
|
transport http {
|
|
read_timeout 180s
|
|
write_timeout 180s
|
|
}
|
|
}
|
|
}
|
|
|
|
# Geo API - institution data and stats
|
|
handle /api/geo/* {
|
|
uri strip_prefix /api/geo
|
|
reverse_proxy 127.0.0.1:8002 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
# Cache API - Qdrant-backed semantic cache (same backend as RAG)
|
|
handle /api/cache/* {
|
|
reverse_proxy 127.0.0.1:8010 {
|
|
transport http {
|
|
read_timeout 30s
|
|
write_timeout 30s
|
|
}
|
|
}
|
|
}
|
|
|
|
# Fallback API proxy - shared backend with bronhouder.nl
|
|
handle /api/* {
|
|
reverse_proxy 127.0.0.1:8000 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
# DuckLake analytics API
|
|
handle /ducklake/* {
|
|
uri strip_prefix /ducklake
|
|
reverse_proxy 127.0.0.1:8765 {
|
|
transport http {
|
|
read_timeout 120s
|
|
write_timeout 120s
|
|
}
|
|
}
|
|
}
|
|
|
|
# Static files from archief-assistent build
|
|
handle {
|
|
import archief_static_files
|
|
}
|
|
}
|