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
# flexd.conf — example configuration
#
# Copy to flexd.conf and adjust. Run with:
# flexd --config flexd.conf
# Validate without starting:
# flexd --config flexd.conf --test
#
# Paths are resolved relative to the working directory flexd is started from.
[global]
worker_processes = "auto" # or an integer
error_log = "./logs/error.log"
# pid_file = "./flexd.pid"
# user = "www-data" # drop privileges after binding (requires root)
# http_downgrade_policy = "validate"
# [global.timeouts]
# idle = 75
# request = 30
# keepalive = 75
# proxy_read = 60
# ── HTTP server ────────────────────────────────────────────────────────────────
[[http]]
server_name = ["example.com", "www.example.com"]
root = "./public"
access_log = "./logs/access.log"
# Host-header policy: "strict" (default — only server_name values accepted) or "any"
host_header_policy = "strict"
# Upstream targets resolving to loopback/private ranges must be explicitly allowed.
# upstream_allowed_networks = ["127.0.0.0/8"]
# Request limits (bytes)
# max_header_size = 16384
# max_header_count = 100
# max_body_size = 10485760
[[http.listen]]
port = 8080
protocol = "tcp"
# ── Static files ───────────────────────────────────────────────────────────────
[[http.locations]]
pattern = "/"
match_type = "prefix"
[http.locations.handler]
type = "static"
root = "./public"
# ── Reverse proxy ──────────────────────────────────────────────────────────────
[[http.locations]]
pattern = "/api/"
match_type = "prefix"
[http.locations.handler]
type = "proxy"
[http.locations.handler.upstream]
name = "backend"
strategy = "round-robin"
[[http.locations.handler.upstream.servers]]
address = "127.0.0.1:3000"
weight = 1
# ── HTTPS with ACME (Let's Encrypt) ────────────────────────────────────────────
# Uncomment and adjust. flexd obtains and renews certificates automatically.
#
# [[http]]
# server_name = ["example.com"]
# root = "./public"
# http2 = true
# http3 = true # QUIC; listen protocol below must include udp
#
# [[http.listen]]
# port = 443
# protocol = "tcp"
#
# [http.ssl]
# protocols = ["TLSv1.2", "TLSv1.3"]
#
# [http.ssl.acme]
# enabled = true
# email = "admin@example.com"
# domains = ["example.com"]
# agree_tos = true
# staging = false # true = Let's Encrypt staging CA
# challenge_types = ["http-01", "tls-alpn-01"]
# cert_dir = "./acme" # issued cert/key persisted here (mode 0600)
# renewal_window = 30 # days before expiry to renew
#
# Static certificate instead of ACME:
# [http.ssl]
# certificate = "./certs/example.com.pem"
# certificate_key = "./certs/example.com.key"
# ── TCP stream proxy ───────────────────────────────────────────────────────────
#
# [[stream]]
# [stream.listen]
# port = 5432
# protocol = "tcp"
#
# [stream.upstream]
# name = "db"
# [[stream.upstream.servers]]
# address = "10.0.0.5:5432"