all repos — flynet @ 9e8083e56923c20b5a9dd80c86b21738ae1a9c29

ersatz CDN on fly.io

Caddyfile (view raw)

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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
{
	persist_config off

	servers {
		protocols h1 h2
	}

	cache {
		ttl 1h
		simplefs {
			configuration {
				path /data
				directory_size 900MB
			}
		}
		storers simplefs
	}
	log {
		format json
		exclude admin.api
	}

	order goatcounter after tracing

	metrics {
		per_host
	}

	acme_ca https://acme-api.actalis.com/acme/directory
	acme_eab {
		key_id {$EAB_KEY_ID}
		mac_key {$EAB_MAC_KEY}
	}

	storage redis {
		host redis.alin.ovh
		username default
		db 1
		password {$REDIS_PASSWORD}
		encryption_key {$REDIS_ENCRYPTION_KEY}
		tls_enabled true
		tls_insecure false
	}
}

(dns01) {
	tls {
		dns rfc2136 {
			key_name caddy
			key_alg hmac-sha512
			key {env.DDNS_TSIG_KEY}
			server pdns.alin.ovh:53
		}
	}
}

(cache) {
	cache
	header -Server
}

(rate_limit) {
	rate_limit {
		distributed
		zone global_static {
			match {
				query query=*
			}
			key static
			events 100
			window 1m
		}
		zone host_dynamic {
			match {
				query query=*
			}
			key {remote_host}
			events 5
			window 10s
		}
	}
}

flynet-butterfly-1123.fly.dev {
	respond "Hello, world!"
}

alanpearce.eu, alin.ovh, www.alin.ovh, www.alanpearce.eu {
	import cache

	goatcounter {
		api_host https://stats.alin.ovh
		site stats.alin.ovh
		token {$GOATCOUNTER_TOKEN}
	}

	reverse_proxy https://homestead-homestead488.danubedata.run {
		header_up Host {hostport}
	}
}

uptime.alin.ovh,
status.alin.ovh,
status.searchix.ovh {
	import cache
	reverse_proxy https://home.alin.ovh {
		header_up Host {hostport}
		header_down -Alt-Svc
	}
}

searchix.ovh {
	import cache
	import rate_limit

	goatcounter {
		api_host https://stats.searchix.ovh
		site stats.searchix.ovh
		token {$GOATCOUNTER_TOKEN}
	}

	reverse_proxy {
		to https://smrk.alin.ovh https://home.alin.ovh
		lb_policy first

		header_up Host {hostport}
		header_down -Alt-Svc

		# active health checks (service running)
		health_uri /health
		health_headers {
			Host {hostport}
		}
		health_status 2xx
		health_interval 10s
		health_timeout 5s
		health_fails 2

		# passive health checks
		max_fails 5
		fail_duration 30s
		unhealthy_status 5xx
	}
}

stable.searchix.ovh {
	import cache
	import rate_limit

	goatcounter {
		api_host https://stats.stable.searchix.ovh
		site stats.stable.searchix.ovh
		token {$GOATCOUNTER_TOKEN}
	}

	reverse_proxy {
		to https://smrk.alin.ovh
		lb_policy first

		header_up Host {hostport}
		header_down -Alt-Svc

		# active health checks (service running)
		health_uri /health
		health_headers {
			Host {hostport}
		}
		health_status 2xx
		health_interval 10s
		health_timeout 5s
		health_fails 2

		# passive health checks
		max_fails 5
		fail_duration 30s
		unhealthy_status 5xx
	}
}