1. The problem I’m having:
I’m trying to set up a Caddy server to host a Single Page Application (SPA) and reverse proxy API requests to a backend server. The SPA is built with React and located in the /home/ubuntu/WS24-MyDailyImpact/mdi-react/dist directory. I want Caddy to serve the SPA and handle client-side routing, while also proxying API requests to a backend server running on localhost:5001.
The server is running, but it’s not serving the SPA correctly. Instead, it’s responding with 403 HTTP Error status code for all requests.
This is the output of curl:
curl -vL https://mydailyimpact.codecrafter.space/
* Trying 3.67.67.181:443...
* Connected to mydailyimpact.codecrafter.space (3.67.67.181) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /usr/lib/ssl/certs
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=mydailyimpact.codecrafter.space
* start date: Mar 6 03:47:26 2025 GMT
* expire date: Jun 4 03:47:25 2025 GMT
* subjectAltName: host "mydailyimpact.codecrafter.space" matched cert's "mydailyimpact.codecrafter.space"
* issuer: C=US; O=Let's Encrypt; CN=E6
* SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* Using Stream ID: 1 (easy handle 0x5d2878f6e9f0)
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET / HTTP/2
> Host: mydailyimpact.codecrafter.space
> user-agent: curl/7.81.0
> accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 403
< alt-svc: h3=":443"; ma=2592000
< server: Caddy
< content-length: 0
< date: Thu, 06 Mar 2025 07:39:54 GMT
<
* Connection #0 to host mydailyimpact.codecrafter.space left intact
However, when I run:
sudo caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
It works.
2. Error messages and/or full log output:
Mar 06 07:43:25 ip-172-26-3-4 systemd[1]: Started Caddy.
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.9325602,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.9347594,"msg":"adapted config to JSON","adapter":"caddyfile"}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"warn","ts":1741247005.934786,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":6}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.936095,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//127.0.0.1:2019","//localhost:2019","//[::1]:2019"]}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.936409,"logger":"http.auto_https","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.93643,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247005.9364662,"logger":"http.auto_https","msg":"adjusted config","tls":{"automation":{"policies":[{}]}},"http":{"servers":{"remaining_auto_https_redirects":{"listen":[":80"],"routes":[{},{}],"logs":{"logger_names":{"mydailyimpact.codecrafter.space":["log0"]}}},"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"vars","root":"/home/ubuntu/WS24-MyDailyImpact/mdi-react/dist"}]},{"handle":[{"handler":"rewrite","uri":"{http.matchers.file.relative}"}],"match":[{"file":{"try_files":["{http.request.uri.path}","/index.html"]}}]},{"handle":[{"encodings":{"gzip":{}},"handler":"encode","prefer":["gzip"]}]},{"group":"group2","handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"rewrite","strip_path_prefix":"/auth"}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"localhost:5001"}]}]}]}],"match":[{"path":["/auth/*"]}]},{"group":"group2","handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"rewrite","strip_path_prefix":"/api"}]},{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"localhost:5001"}]}]}]}],"match":[{"path":["/api/*"]}]},{"handle":[{"handler":"file_server","hide":["/etc/caddy/Caddyfile"]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{},"logs":{"logger_names":{"mydailyimpact.codecrafter.space":["log0"]}}}}}}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.9367528,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0007a5880"}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247005.937794,"logger":"http","msg":"starting server loop","address":"[::]:443","tls":true,"http3":false}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.938387,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.938477,"msg":"failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details."}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.9386013,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247005.938654,"logger":"http","msg":"starting server loop","address":"[::]:80","tls":false,"http3":false}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"warn","ts":1741247005.9386628,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"warn","ts":1741247005.9386675,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.9386718,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.938677,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["mydailyimpact.codecrafter.space"]}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247005.9392369,"logger":"tls.cache","msg":"added certificate to cache","subjects":["mydailyimpact.codecrafter.space"],"expiration":1749008846,"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"676c3133f7fbc24e86f2187538474f15f634712e0c41c331a9b5679761056061","cache_size":1,"cache_capacity":10000}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247005.9392755,"logger":"events","msg":"event","name":"cached_managed_cert","id":"4a200fd1-7f6e-4c1e-bf07-d705908b295b","origin":"tls","data":{"sans":["mydailyimpact.codecrafter.space"]}}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.9394221,"msg":"autosaved config (load with --resume flag)","file":"/var/lib/caddy/.config/caddy/autosave.json"}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.9394314,"msg":"serving initial configuration"}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.942718,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/var/lib/caddy/.local/share/caddy","instance":"3b4db656-0fd5-4b66-ab71-4eccc5c39ba9","try_again":1741333405.9427145,"try_again_in":86399.999999629}
Mar 06 07:43:25 ip-172-26-3-4 caddy[55625]: {"level":"info","ts":1741247005.942792,"logger":"tls","msg":"finished cleaning storage units"}
Mar 06 07:43:38 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247018.4561512,"logger":"events","msg":"event","name":"tls_get_certificate","id":"aace6fb5-724f-4e6d-8b4c-1d0e2e3693a9","origin":"tls","data":{"client_hello":{"CipherSuites":[4866,4867,4865,49196,49200,159,52393,52392,52394,49195,49199,158,49188,49192,107,49187,49191,103,49162,49172,57,49161,49171,51,157,156,61,60,53,47,255],"ServerName":"mydailyimpact.codecrafter.space","SupportedCurves":[29,23,30,25,24,256,257,258,259,260],"SupportedPoints":"AAEC","SignatureSchemes":[1027,1283,1539,2055,2056,2057,2058,2059,2052,2053,2054,1025,1281,1537,771,769,770,1026,1282,1538],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771],"RemoteAddr":{"IP":"3.67.67.181","Port":45098,"Zone":""},"LocalAddr":{"IP":"172.26.3.4","Port":443,"Zone":""}}}}
Mar 06 07:43:38 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247018.4564464,"logger":"tls.handshake","msg":"choosing certificate","identifier":"mydailyimpact.codecrafter.space","num_choices":1}
Mar 06 07:43:38 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247018.4564588,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"mydailyimpact.codecrafter.space","subjects":["mydailyimpact.codecrafter.space"],"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"676c3133f7fbc24e86f2187538474f15f634712e0c41c331a9b5679761056061"}
Mar 06 07:43:38 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247018.4564705,"logger":"tls.handshake","msg":"matched certificate in cache","remote_ip":"3.67.67.181","remote_port":"45098","subjects":["mydailyimpact.codecrafter.space"],"managed":true,"expiration":1749008846,"hash":"676c3133f7fbc24e86f2187538474f15f634712e0c41c331a9b5679761056061"}
Mar 06 07:43:38 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247018.461961,"logger":"http.handlers.file_server","msg":"sanitized path join","site_root":"/home/ubuntu/WS24-MyDailyImpact/mdi-react/dist","fs":"","request_path":"/","result":"/home/ubuntu/WS24-MyDailyImpact/mdi-react/dist"}
Mar 06 07:43:38 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247018.4620721,"logger":"http.log.error.log0","msg":"open /home/ubuntu/WS24-MyDailyImpact/mdi-react/dist: permission denied","request":{"remote_ip":"3.67.67.181","remote_port":"45098","client_ip":"3.67.67.181","proto":"HTTP/2.0","method":"GET","host":"mydailyimpact.codecrafter.space","uri":"/","headers":{"User-Agent":["curl/7.81.0"],"Accept":["*/*"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"mydailyimpact.codecrafter.space"}},"duration":0.000766447,"status":403,"err_id":"jj0re8b2u","err_trace":"fileserver.(*FileServer).ServeHTTP (staticfiles.go:306)"}
Mar 06 07:45:45 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247145.1981063,"logger":"events","msg":"event","name":"tls_get_certificate","id":"8e7b08c0-6ed4-4caa-b271-4d8b8394462a","origin":"tls","data":{"client_hello":{"CipherSuites":[4866,4865,4867,49196,49195,52393,49200,49199,52392,255],"ServerName":"mydailyimpact.codecrafter.space","SupportedCurves":[29,23,24],"SupportedPoints":"AA==","SignatureSchemes":[1283,1027,2055,2054,2053,2052,1537,1281,1025],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771],"RemoteAddr":{"IP":"4.227.36.69","Port":49702,"Zone":""},"LocalAddr":{"IP":"172.26.3.4","Port":443,"Zone":""}}}}
Mar 06 07:45:45 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247145.1982105,"logger":"tls.handshake","msg":"choosing certificate","identifier":"mydailyimpact.codecrafter.space","num_choices":1}
Mar 06 07:45:45 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247145.1982224,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"mydailyimpact.codecrafter.space","subjects":["mydailyimpact.codecrafter.space"],"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"676c3133f7fbc24e86f2187538474f15f634712e0c41c331a9b5679761056061"}
Mar 06 07:45:45 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247145.1982322,"logger":"tls.handshake","msg":"matched certificate in cache","remote_ip":"4.227.36.69","remote_port":"49702","subjects":["mydailyimpact.codecrafter.space"],"managed":true,"expiration":1749008846,"hash":"676c3133f7fbc24e86f2187538474f15f634712e0c41c331a9b5679761056061"}
Mar 06 07:45:45 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247145.344055,"logger":"http.handlers.file_server","msg":"sanitized path join","site_root":"/home/ubuntu/WS24-MyDailyImpact/mdi-react/dist","fs":"","request_path":"/robots.txt","result":"/home/ubuntu/WS24-MyDailyImpact/mdi-react/dist/robots.txt"}
Mar 06 07:45:45 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247145.3441472,"logger":"http.log.error.log0","msg":"open /home/ubuntu/WS24-MyDailyImpact/mdi-react/dist/robots.txt: permission denied","request":{"remote_ip":"4.227.36.69","remote_port":"49702","client_ip":"4.227.36.69","proto":"HTTP/2.0","method":"GET","host":"mydailyimpact.codecrafter.space","uri":"/robots.txt","headers":{"Accept":["*/*"],"From":["gptbot(at)openai.com"],"User-Agent":["Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"],"Accept-Encoding":["gzip, br, deflate"],"X-Openai-Host-Hash":["911541922"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"mydailyimpact.codecrafter.space"}},"duration":0.000158789,"status":403,"err_id":"ikkzc7gsv","err_trace":"fileserver.(*FileServer).ServeHTTP (staticfiles.go:306)"}
Mar 06 07:45:45 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247145.6253858,"logger":"events","msg":"event","name":"tls_get_certificate","id":"f2477544-b8ac-453b-9513-bb93f2dd2815","origin":"tls","data":{"client_hello":{"CipherSuites":[4866,4865,4867,49196,49195,52393,49200,49199,52392,255],"ServerName":"mydailyimpact.codecrafter.space","SupportedCurves":[29,23,24],"SupportedPoints":"AA==","SignatureSchemes":[1283,1027,2055,2054,2053,2052,1537,1281,1025],"SupportedProtos":["h2","http/1.1"],"SupportedVersions":[772,771],"RemoteAddr":{"IP":"20.171.207.6","Port":55428,"Zone":""},"LocalAddr":{"IP":"172.26.3.4","Port":443,"Zone":""}}}}
Mar 06 07:45:45 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247145.6255147,"logger":"tls.handshake","msg":"choosing certificate","identifier":"mydailyimpact.codecrafter.space","num_choices":1}
Mar 06 07:45:45 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247145.6255255,"logger":"tls.handshake","msg":"default certificate selection results","identifier":"mydailyimpact.codecrafter.space","subjects":["mydailyimpact.codecrafter.space"],"managed":true,"issuer_key":"acme-v02.api.letsencrypt.org-directory","hash":"676c3133f7fbc24e86f2187538474f15f634712e0c41c331a9b5679761056061"}
Mar 06 07:45:45 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247145.6255367,"logger":"tls.handshake","msg":"matched certificate in cache","remote_ip":"20.171.207.6","remote_port":"55428","subjects":["mydailyimpact.codecrafter.space"],"managed":true,"expiration":1749008846,"hash":"676c3133f7fbc24e86f2187538474f15f634712e0c41c331a9b5679761056061"}
Mar 06 07:45:45 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247145.7660022,"logger":"http.handlers.file_server","msg":"sanitized path join","site_root":"/home/ubuntu/WS24-MyDailyImpact/mdi-react/dist","fs":"","request_path":"/","result":"/home/ubuntu/WS24-MyDailyImpact/mdi-react/dist"}
Mar 06 07:45:45 ip-172-26-3-4 caddy[55625]: {"level":"debug","ts":1741247145.766139,"logger":"http.log.error.log0","msg":"open /home/ubuntu/WS24-MyDailyImpact/mdi-react/dist: permission denied","request":{"remote_ip":"20.171.207.6","remote_port":"55428","client_ip":"20.171.207.6","proto":"HTTP/2.0","method":"GET","host":"mydailyimpact.codecrafter.space","uri":"/","headers":{"X-Openai-Host-Hash":["911541922"],"Accept":["*/*"],"From":["gptbot(at)openai.com"],"User-Agent":["Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"],"Accept-Encoding":["gzip, br, deflate"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"mydailyimpact.codecrafter.space"}},"duration":0.000254741,"status":403,"err_id":"rg9bp8rnf","err_trace":"fileserver.(*FileServer).ServeHTTP (staticfiles.go:306)"}
3. Caddy version:
v2.9.1
4. How I installed and ran Caddy:
I followed the instructions from the official documentation for Ubuntu:
a. System environment:
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.5 LTS"
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
Systemd:
systemd 249 (249.11-0ubuntu3.12)
+PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY -P11KIT -QRENCODE +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified
This is the content of:
sudo cat /etc/systemd/system/caddy.service
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
b. Command:
sudo systemctl start caddy
sudo systemctl enable caddy
sudo systemctl status caddy
d. My complete Caddy config:
{
debug
}
mydailyimpact.codecrafter.space {
root * /home/ubuntu/WS24-MyDailyImpact/mdi-react/dist
encode gzip
file_server
try_files {path} /index.html
handle_path /api/* {
reverse_proxy localhost:5001
}
handle_path /auth/* {
reverse_proxy localhost:5001
}
log {
output file /var/log/caddy/access.log
format json
}
}