···167167```caddy
168168pds.example.com {
169169 encode gzip
170170- reverse_proxy 127.0.0.1:7755
170170+ reverse_proxy 127.0.0.1:7755 {
171171+ transport http {
172172+ keepalive off
173173+ }
174174+ }
171175}
172176```
173177178178+If you run `perlsky` behind Caddy using the single-process `script/perlsky daemon`
179179+listener shown above, disable Caddy's upstream keepalive reuse for that backend.
180180+The Mojolicious daemon closes idle backend sockets after a short timeout, and Caddy
181181+can otherwise reuse a stale upstream connection and surface intermittent `502`
182182+responses on requests such as `com.atproto.server.createSession`. If you use a
183183+different proxy, make sure its upstream keepalive behavior and idle timeouts are
184184+compatible with the backend, or disable upstream reuse there as well.
185185+174186For public user handles you also need a matching wildcard-capable site or on-demand TLS path for `*.pds.example.com`.
175187176188One practical Caddy pattern is on-demand TLS restricted to domains that `perlsky` approves:
···184196185197pds.example.com {
186198 encode gzip
187187- reverse_proxy 127.0.0.1:7755
199199+ reverse_proxy 127.0.0.1:7755 {
200200+ transport http {
201201+ keepalive off
202202+ }
203203+ }
188204}
189205190206https:// {
···195211 @perlsky_handles host *.pds.example.com
196212 handle @perlsky_handles {
197213 encode gzip
198198- reverse_proxy 127.0.0.1:7755
214214+ reverse_proxy 127.0.0.1:7755 {
215215+ transport http {
216216+ keepalive off
217217+ }
218218+ }
199219 }
200220}
201221```
···207227```caddy
208228@blob_download path /xrpc/com.atproto.sync.getBlob
209229handle @blob_download {
210210- reverse_proxy 127.0.0.1:7755
230230+ reverse_proxy 127.0.0.1:7755 {
231231+ transport http {
232232+ keepalive off
233233+ }
234234+ }
211235}
212236213237handle {
214238 encode gzip
215215- reverse_proxy 127.0.0.1:7755
239239+ reverse_proxy 127.0.0.1:7755 {
240240+ transport http {
241241+ keepalive off
242242+ }
243243+ }
216244}
217245```
218246