Repository navigation
Expand file tree
/
Copy pathCaddyfile
More file actions
63 lines (53 loc) · 2.09 KB
/
Copy pathCaddyfile
File metadata and controls
63 lines (53 loc) · 2.09 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
# Production reverse proxy. The only service with published ports.
#
# Caddy terminates TLS (Let's Encrypt, obtained and renewed on its own) for {$DOMAIN} and load-balances across the
# app replicas. Both values come from deploy/.env.prod via compose; nothing here is site-specific.
{
email {$ACME_EMAIL}
# Let's Encrypt rate-limits failed real-certificate attempts hard. While DNS is still propagating, uncomment
# this to get untrusted staging certificates instead, then comment it out again.
# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}
{$DOMAIN} {
encode zstd gzip
# Actuator lives on the management port (8081), which is never proxied. This is a second lock on the same door:
# even if someone moves actuator back to 8080, it stays unreachable from the internet.
@actuator path /actuator*
respond @actuator 404
# Upstreams are resolved from Docker's embedded DNS rather than pinned at startup. A replaced replica gets a new
# container IP; re-resolving every 5 seconds picks it up with no reload, which is what lets Watchtower roll
# replicas underneath us.
reverse_proxy {
dynamic a {
name app
port 8080
refresh 5s
}
# Dynamic upstreams cannot use active health checks, so health is passive: a replica that refuses a connection
# is taken out of rotation for fail_duration. Deliberately NOT on 5xx responses: one buggy endpoint must not
# eject a replica that serves every other route fine.
fail_duration 10s
max_fails 1
# Retry only on connection-level failure: the request never reached the application, so re-sending it cannot
# double-apply anything. A request that was accepted and then errored is returned to the client untouched.
lb_policy round_robin
lb_try_duration 5s
lb_try_interval 250ms
transport http {
dial_timeout 2s
response_header_timeout 60s
}
header_up X-Real-IP {remote_host}
}
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
log {
output stdout
format json
}
}