Caddyfile Configuration
Complete Caddyfile configuration reference for the Productify Proxy.
Basic Structure
nginx
{
# Global options block
security {
# OAuth2/OIDC configuration
}
productify {
# Manager integration
}
}
site.com {
# Site-specific configuration
}Global Options
nginx
{
# Admin API
admin off # Disable admin API (production)
# admin :2019 # Enable on port 2019
# Email for Let's Encrypt
email admin@example.com
# Auto HTTPS
auto_https on # Enable automatic HTTPS
# auto_https off # Disable for local dev
# Default SNI
default_sni example.com
# Grace period for config changes
grace_period 10s
}Security Configuration
OAuth2 Identity Provider
nginx
{
security {
oauth identity provider generic {
delay_start 1
retry_attempts 3
retry_interval 2
realm generic
driver generic
client_id ab098fe1-9bc0-4780-81c6-2ea17f49a3cb
client_secret pU3ZrOyPTtd4A3ex16dBzBTlDrlxqfpU
scopes openid email profile
base_auth_url http://pocketid.localhost
metadata_url http://pocketid.localhost/.well-known/openid-configuration
}
}
}Authentication Portal
nginx
{
security {
authentication portal pocketportal {
crypto default token lifetime 3600
enable identity provider generic
cookie insecure on # Only for local dev!
transform user {
match realm generic
action add role user
}
}
}
}Authorization Policy
nginx
{
security {
authorization policy pocketpolicy {
set auth url /auth/oauth2/generic
allow roles user
validate bearer header
inject headers with claims
enable strip token
}
}
}Productify Manager Integration
Configure the Productify plugin to communicate with the Manager API:
nginx
{
productify {
manager http://172.17.0.1:8080
token supersecrettoken
enable_access_log # Enable detailed access logging
enable_metrics # Enable request count and response time metrics
enable_size_metrics # Enable request/response size metrics
}
}Configuration Options
| Option | Type | Required | Description |
|---|---|---|---|
manager | string | Yes | URL of the Productify Manager API |
token | string | Yes | Authentication token for Manager API |
enable_access_log | flag | No | Enable structured access logging |
enable_metrics | flag | No | Enable Prometheus metrics |
enable_size_metrics | flag | No | Enable request/response size metrics |
Monitoring Options:
enable_access_log: Logs every request with source IP, user, user agent, target system, method, path, and timestampenable_metrics: Exposes Prometheus metrics for request count and response time on:2112/metricsenable_size_metrics: Adds request and response size metrics (requiresenable_metrics)
See Monitoring & Logging for detailed information about metrics and logs.
Application Routing
Single Application
nginx
http://app.localhost {
@auth {
path /auth/*
}
route @auth {
productify_before_auth with 123
authenticate with pocketportal
}
route /* {
authorize with pocketpolicy
productify with 123
reverse_proxy backend:8080
}
}Multiple Applications
nginx
http://app1.localhost {
route /* {
authorize with pocketpolicy
productify with 100
reverse_proxy app1:8080
}
}
http://app2.localhost {
route /* {
authorize with pocketpolicy
productify with 200
reverse_proxy app2:8080
}
}Path-Based Routing
nginx
apps.productify.dev {
route /app1/* {
authorize with pocketpolicy
productify with 100
uri strip_prefix /app1
reverse_proxy app1:8080
}
route /app2/* {
authorize with pocketpolicy
productify with 200
uri strip_prefix /app2
reverse_proxy app2:8080
}
}Manager Integration
nginx
manager.productify.dev {
@auth {
path /auth/*
}
route @auth {
authenticate with pocketportal
}
route /* {
authorize with pocketpolicy
reverse_proxy manager:8080
}
}} }
## Load Balancing
### Round Robin
```nginx
app.example.com {
reverse_proxy backend1:8080 backend2:8080 backend3:8080 {
lb_policy round_robin
}
}Least Connections
nginx
app.example.com {
reverse_proxy backend1:8080 backend2:8080 {
lb_policy least_conn
}
}IP Hash
nginx
app.example.com {
reverse_proxy backend1:8080 backend2:8080 {
lb_policy ip_hash
}
}Health Checks
nginx
app.example.com {
reverse_proxy backend1:8080 backend2:8080 {
# Health check configuration
health_uri /health
health_interval 10s
health_timeout 5s
health_status 200
# Fail threshold
fail_duration 30s
max_fails 3
unhealthy_status 503
}
}TLS Configuration
Automatic HTTPS
nginx
{
email admin@example.com
}
example.com {
# Caddy automatically obtains and renews certificates
reverse_proxy backend:8080
}Custom Certificates
nginx
example.com {
tls /path/to/cert.pem /path/to/key.pem
reverse_proxy backend:8080
}TLS Client Authentication
nginx
example.com {
tls {
client_auth {
mode require_and_verify
trusted_ca_cert_file /path/to/ca.pem
}
}
reverse_proxy backend:8080
}Authentication
Basic Auth
nginx
admin.example.com {
basicauth {
admin $2a$14$... # bcrypt hash
}
reverse_proxy backend:8080
}OAuth2 Authentication
nginx
app.example.com {
@auth {
path /auth/*
}
route @auth {
authenticate with pocketportal
}
route /* {
authorize with pocketpolicy
reverse_proxy backend:8080
}
}Bearer Token Validation
nginx
api.example.com {
route /api/* {
# Policy validates bearer header
authorize with pocketpolicy
reverse_proxy backend:8080
}
}Headers
Security Headers
nginx
example.com {
header {
# Security headers
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
X-XSS-Protection "1; mode=block"
# Remove server header
-Server
}
reverse_proxy backend:8080
}CORS Headers
nginx
api.example.com {
header {
Access-Control-Allow-Origin "https://app.example.com"
Access-Control-Allow-Methods "GET, POST, PUT, DELETE"
Access-Control-Allow-Headers "Content-Type, Authorization"
}
reverse_proxy backend:8080
}Logging
Access Logs
nginx
{
log {
output file /var/log/caddy/access.log {
roll_size 100mb
roll_keep 10
roll_keep_for 30d
}
format json
level info
}
}Per-Site Logging
nginx
example.com {
log {
output file /var/log/caddy/example.log
format json
}
reverse_proxy backend:8080
}Complete Example
nginx
{
email admin@productify.dev
admin off
security {
oauth identity provider generic {
realm generic
driver generic
client_id ab098fe1-9bc0-4780-81c6-2ea17f49a3cb
client_secret pU3ZrOyPTtd4A3ex16dBzBTlDrlxqfpU
scopes openid email profile
base_auth_url http://pocketid.localhost
metadata_url http://pocketid.localhost/.well-known/openid-configuration
}
authentication portal pocketportal {
crypto default token lifetime 3600
enable identity provider generic
cookie insecure on
transform user {
match realm generic
action add role user
}
}
authorization policy pocketpolicy {
set auth url /auth/oauth2/generic
allow roles user
validate bearer header
inject headers with claims
enable strip token
}
}
productify {
manager http://172.17.0.1:8080
token supersecrettoken
}
log {
output file /var/log/caddy/access.log
format json
}
}
# Identity Provider
http://pocketid.localhost {
reverse_proxy pocketid:1411
}
# Application with authentication
http://app.localhost {
@auth {
path /auth/*
}
route @auth {
productify_before_auth with 123
authenticate with pocketportal
}
route /* {
authorize with pocketpolicy
productify with 123
file_server {
root /usr/share/caddy
browse
}
}
log {
output file /var/log/caddy/app.log
}
}
# Manager UI/API
http://manager.localhost {
@auth {
path /auth/*
}
route @auth {
authenticate with pocketportal
}
route /* {
authorize with pocketpolicy
reverse_proxy 172.17.0.1:8080
}
log {
output file /var/log/caddy/manager.log
}
}