-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCaddyfile
More file actions
126 lines (114 loc) · 5.51 KB
/
Caddyfile
File metadata and controls
126 lines (114 loc) · 5.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# Nexus Caddyfile
#
# Usage:
# Development (LAN, no TLS):
# caddy run --config Caddyfile
#
# Production (public domain with auto-TLS):
# Set NEXUS_DOMAIN below and run: caddy run --config Caddyfile
# Or via docker compose: see deploy/docker-compose.prod.yml
#
# Caddy automatically provisions and renews Let's Encrypt certificates for
# public hostnames. For LAN/local use it serves plain HTTP.
#
# Environment variables (set in .env or export before running):
# NEXUS_DOMAIN — Public hostname (default: localhost)
# NEXUS_WEB_ROOT — Path to built nexus-web dist/ directory
# (default: packages/nexus-web/dist)
# ── Global options ─────────────────────────────────────────────────────────────
{
# Email for Let's Encrypt registration (required for auto-TLS on public domains)
# email admin@{$NEXUS_DOMAIN:localhost}
#
# Uncomment and fill in for production:
# email your@email.com
}
# ── Main site ──────────────────────────────────────────────────────────────────
{$NEXUS_DOMAIN:localhost} {
# ── REST API ───────────────────────────────────────────────────────────────
handle /api/* {
reverse_proxy localhost:8080
}
# ── WebSocket gateway (real-time events) ───────────────────────────────────
handle /gateway {
reverse_proxy localhost:8081 {
# Preserve WebSocket upgrade
header_up Connection {>Connection}
header_up Upgrade {>Upgrade}
# Long timeout for persistent WebSocket connections
transport http {
dial_timeout 5s
response_header_timeout 0
}
}
}
# ── Voice signaling WebSocket ──────────────────────────────────────────────
handle /voice/ws {
reverse_proxy localhost:8082 {
header_up Connection {>Connection}
header_up Upgrade {>Upgrade}
transport http {
dial_timeout 5s
response_header_timeout 0
}
}
}
# ── Federation & Matrix bridge endpoints ──────────────────────────────────
handle /_nexus/* {
reverse_proxy localhost:8080
}
handle /.well-known/nexus/* {
reverse_proxy localhost:8080
}
handle /.well-known/matrix/* {
reverse_proxy localhost:8080
}
handle /_matrix/* {
reverse_proxy localhost:8080
}
# ── Prometheus metrics — deny external access ─────────────────────────────
handle /metrics {
respond 403
}
# ── Web client (nexus-web SPA) — serve static files ──────────────────────
handle {
root * {$NEXUS_WEB_ROOT:packages/nexus-web/dist}
# Try the exact file first, then the directory index, then fall back
# to index.html for client-side routing (react-router-dom)
try_files {path} {path}/ /index.html
file_server
# Cache hashed assets aggressively; index.html must not be cached
@hashed path_regexp hashed \.[0-9a-f]{8,}\.(js|css|woff2?)$
header @hashed Cache-Control "public, max-age=31536000, immutable"
header /index.html Cache-Control "no-cache, no-store, must-revalidate"
}
# ── Security headers ───────────────────────────────────────────────────────
header {
# Prevent MIME sniffing
X-Content-Type-Options "nosniff"
# Prevent clickjacking
X-Frame-Options "DENY"
# HSTS (2 years) — enable only when you're confident in TLS
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
# Referrer policy
Referrer-Policy "strict-origin-when-cross-origin"
# Permissions policy
Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()"
# Content security policy for the web client
Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; connect-src 'self' wss: ws:; font-src 'self'; media-src 'self' blob:; worker-src 'self' blob:; frame-ancestors 'none'"
# Remove server identification
-Server
}
# ── Logging ────────────────────────────────────────────────────────────────
log {
output stdout
format console
level INFO
}
}
# ── Optional: separate admin subdomain ────────────────────────────────────────
# Uncomment and configure if you deploy the admin dashboard separately.
#
# admin.{$NEXUS_DOMAIN:localhost} {
# reverse_proxy localhost:8090
# }