1. The problem I’m having:
I have a public nginx which is removing the https request and pass it through to caddy as http.
I would like to map different paths to different backend services.
I think there is something missing regarding the first reverse proxy calling caddy, because if I try to connect via wget on the machine I can access the backend services.
curl -vL https://cloud..../uptime
* Host cloud....:443 was resolved.
* IPv6: (none)
* IPv4: 45.144....
* Trying 45.144....:443...
* Connected to cloud.... (45.144....) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/cert.pem
* CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
* subject: CN=cloud....
* start date: Sep 18 11:18:11 2025 GMT
* expire date: Dec 17 11:18:10 2025 GMT
* subjectAltName: host "cloud...." matched cert's "cloud...."
* issuer: C=US; O=Let's Encrypt; CN=R12
* SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://cloud..../uptime
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: cloud....]
* [HTTP/2] [1] [:path: /uptime]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
> GET /uptime HTTP/2
> Host: cloud....
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/2 200
< date: Fri, 19 Sep 2025 16:55:52 GMT
< content-length: 0
< strict-transport-security: max-age=15724800; includeSubDomains
<
* Connection #0 to host cloud.... left intact
2. Error messages and/or full log output:
{
"level": "info",
"ts": 1758301203.150556,
"logger": "http.log.access",
"msg": "NOP",
"request": {
"remote_ip": "100.119.85.210",
"remote_port": "53972",
"client_ip": "100.119.85.210",
"proto": "HTTP/1.1",
"method": "GET",
"host": "cloud....",
"uri": "/favicon.ico",
"headers": {
"X-Forwarded-Proto": [
"https"
],
"Sec-Fetch-Mode": [
"no-cors"
],
"X-Real-Ip": [
"62...."
],
"X-Scheme": [
"https"
],
"Priority": [
"u=1, i"
],
"X-Request-Id": [
"5ef6f82a19bb0752aa63507c016f503c"
],
"Sec-Ch-Ua": [
"\"Chromium\";v=\"140\", \"Not=A?Brand\";v=\"24\", \"Google Chrome\";v=\"140\""
],
"Dnt": [
"1"
],
"Accept": [
"image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
],
"Accept-Language": [
"de,en;q=0.9"
],
"Referer": [
"https://cloud..../uptime/"
],
"X-Forwarded-Scheme": [
"https"
],
"Sec-Ch-Ua-Platform": [
"\"macOS\""
],
"Sec-Fetch-Dest": [
"image"
],
"Sec-Ch-Ua-Mobile": [
"?0"
],
"Accept-Encoding": [
"gzip, deflate, br, zstd"
],
"X-Forwarded-Host": [
"cloud...."
],
"Sec-Fetch-Site": [
"same-origin"
],
"X-Forwarded-For": [
"62...."
],
"X-Forwarded-Port": [
"443"
],
"User-Agent": [
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36"
]
}
},
"bytes_read": 0,
"user_id": "",
"duration": 0.000004567,
"size": 0,
"status": 0,
"resp_headers": {
"Server": [
"Caddy"
]
}
}
3. Caddy version:
v2.10.2 h1:g/gTYjGMD0dec+UgMw8SnfmJ3I9+M2TdvoRL/Ovu6U8=
4. How I installed and ran Caddy:
library/caddy:latest
a. System environment:
Docker / Kubernetes environment
b. Command:
caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
c. Service/unit/compose file:
-
d. My complete Caddy config:
{
log default {
level DEBUG
output file /var/log/caddy/access.log {
roll_size 10mb
roll_keep 20
roll_keep_for 720h
}
}
debug
}
http://* {
log {
output file /var/log/caddy/vhost.access.log
}
reverse_proxy /uptime http://uptime-kuma:3001 {
}
# pgadmin
handle /abc/* {
header X-Forwarded-Proto http
uri strip_prefix /abc
reverse_proxy http://postgres-admin:80
}
# uptime
# handle /uptime/* {
#header X-Forwarded-Proto http
#uri strip_prefix /uptime
# reverse_proxy http://uptime-kuma:3001
#}
}