Config files for my server. Except not my secrets
1{
2 debug
3 email {$ADMIN_EMAIL:404@vielle.dev}
4 on_demand_tls {
5 ask http://pi:8000/tls-check
6 }
7}
8
9(error) {
10 handle_errors {
11 @custom_err file /{err.status_code}.html
12 handle @custom_err {
13 rewrite * {file_match.relative}
14 file_server
15 }
16 }
17
18 handle_errors {
19 respond "{err.status_code} {err.status_text}"
20 }
21}
22
23(did-web) {
24 handle /.well-known/atproto-did {
25 header Access-Control-Allow-Origin "*"
26 respond "did:web:{args[0]}"
27 }
28
29 handle /.well-known/did.json {
30 header Content-Type "application/json"
31 header Access-Control-Allow-Origin "*"
32 respond <<JSON
33 {
34 "@context": [
35 "https://www.w3.org/ns/did/v1",
36 "https://w3id.org/security/multikey/v1",
37 "https://w3id.org/security/suites/secp256k1-2019/v1"
38 ],
39 "id": "did:web:{args[0]}",
40 "alsoKnownAs": [
41 "at://{args[1]}"
42 ],
43 "verificationMethod": [
44 {
45 "id": "did:web:{args[0]}#atproto",
46 "type": "Multikey",
47 "controller": "did:web:{args[0]}",
48 "publicKeyMultibase": "{args[2]}"
49 }
50 ],
51 "service": [
52 {
53 "id": "#atproto_pds",
54 "type": "AtprotoPersonalDataServer",
55 "serviceEndpoint": "https://{args[3]}"
56 }
57 ]
58 }
59 JSON 200
60 }
61}
62
63(log) {
64 log {args[0]} {
65 output stdout
66 format console
67 }
68}
69
70## main site
71www.{$HOST:vielle.dev} {
72 redir https://{$HOST:vielle.dev}{uri}
73}
74
75{$HOST:vielle.dev} {
76 import log prs
77 reverse_proxy prs:4321
78}
79
80## dongs.zip
81{$DONG_HOST:dongs.zip} {
82 import log dong
83 import did-web "{$DONG_HOST:dongs.zip}" "{$DONG_HOST:dongs.zip}" "zQ3sha8L4YgButkPAFtN4LB2cNai6bBbm7yFJ2kS5iG6KySxd", "pds.vielle.dev"
84 import error
85
86 encode
87 root /srv/dong
88 file_server
89}
90
91## misc did:web
92alt.{$HOST:vielle.dev} {
93 import did-web "alt.{$HOST:vielle.dev}" "alt.{$HOST:vielle.dev}" "zQ3shpgbkbxvf5UjBwQcnjf68rg2DKTRQSttBEGokZbx2BzxY" "pds.vielle.dev"
94}
95
96## send old dong.vielle.dev => dongs.zip
97dong.{$HOST:vielle.dev} {
98 redir https://{$DONG_HOST:dongs.zip}{uri}
99}
100
101## toy projects
102saltire-the-gays.{$HOST:vielle.dev} {
103 import log saltire
104 encode
105 root /srv/saltire
106 import error
107 file_server
108}
109
110## personal projects
111dnd.{$HOST:vielle.dev} {
112 import log dnd
113 encode
114 root /srv/dnd
115 import error
116 file_server
117}
118
119mc.{$HOST:vielle.dev} {
120 import log mc
121 encode
122 root /srv/mc.vielle.dev
123 import error
124 file_server
125}
126
127## atproto services
128### pds
129pds.{$HOST:vielle.dev}, *.pds.{$HOST:vielle.dev}, *.at.{$HOST:vielle.dev}, *.at.{$DONG_HOST:dongs.zip} {
130 import log pds
131 tls {
132 on_demand
133 }
134
135 rewrite / /pds
136 @landing path /pds /styles.css
137 reverse_proxy @landing landing:8000
138
139 # disable age assurance
140 handle /xrpc/app.bsky.ageassurance.getState {
141 header content-type "application/json"
142 header access-control-allow-headers "authorization,dpop,atproto-accept-labelers,atproto-proxy"
143 header access-control-allow-origin "*"
144 respond `{"state":{"lastInitiatedAt":"2025-07-14T14:22:43.912Z","status":"assured","access":"full"},"metadata":{"accountCreatedAt":"2022-11-17T00:35:16.391Z"}}` 200
145 }
146
147 # pds gatekeeper
148 @gatekeeper {
149 path /xrpc/com.atproto.server.getSession
150 path /xrpc/com.atproto.server.describeServer
151 path /xrpc/com.atproto.server.updateEmail
152 path /xrpc/com.atproto.server.createSession
153 path /xrpc/com.atproto.server.createAccount
154 path /@atproto/oauth-provider/~api/sign-in
155 path /gate/*
156 }
157
158 handle @gatekeeper {
159 reverse_proxy {$ADDR_PDS_GATEKEEPER}
160 }
161
162 reverse_proxy {$ADDR_PDS} {
163 transport http {
164 dial_timeout 5s
165 }
166 }
167}
168
169### tangled knot
170# (see nginx.conf for ssh proxying)
171knot.{$HOST:vielle.dev} {
172 import log knot
173 rewrite / /knot
174 @landing path /knot /styles.css
175 reverse_proxy @landing landing:8000
176
177 reverse_proxy {$ADDR_KNOT}
178}
179
180### piper instance
181# technically publicly visible... its _fine_ (+ i cant do jack shit abt it rn so)
182piper.{$HOST:vielle.dev} {
183 import log piper
184 reverse_proxy {$ADDR_PIPER}
185}
186
187##### tmp web dev telephone cimd
188cimd.{$HOST:vielle.dev} {
189 import log cimd
190
191 handle /oauth-client-metadata.json {
192 header Content-Type "application/json"
193 header Access-Control-Allow-Origin "*"
194 respond <<JSON
195 {
196 "client_id": "https://cimd.{$HOST:vielle.dev}/oauth-client-metadata.json",
197 "application_type": "web",
198 "grant_types": ["authorization_code"],
199 "scope": "atproto transition:generic",
200 "response_types": ["code"],
201 "redirect_uris": [
202 "https://cimd.{$HOST:vielle.dev}",
203 "https://cimd.{$HOST:vielle.dev}/oauth/callback",
204 "https://cimd.{$HOST:vielle.dev}/atproto/callback"
205 ],
206 "token_endpoint_auth_method": "none",
207 "dpop_bound_access_tokens": true,
208 "client_name": "cimd.{$HOST:vielle.dev}",
209 "client_uri": "https://cimd.{$HOST:vielle.dev}"
210 }
211 JSON 200
212 }
213
214 @not-oauth `{path} != "/oauth-client-metadata.json"`
215 handle @not-oauth {
216 redir http://localhost:3000{uri}
217 }
218}