Apologies, should have filled all items of the form.
We use a custom docker image based at caddy 2.4.5. This is our Dockerfile:
FROM caddy:2.4.5-builder AS builder
RUN xcaddy build --output ./caddy \
--with github.com/caddyserver/format-encoder
FROM caddy:2.4.5
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
We start our service like this:
docker run --rm --name='proxy' \
--mount type=bind,source=/etc/caddy_config.json,destination=/caddy_config.json \
--publish 80:80 \
--publish 443:443 \
custom/caddy:2.4.5 caddy run --config /caddy_config.json
I have changed logging as per your instructions and compiled a few log entries.
Here is one where an offline upstream node is hit first. The proxy behaves as intended and moves on to a healthy node after 2 seconds:
{
"level":"debug",
"ts":1636466502.3905368,
"logger":"http.handlers.reverse_proxy",
"msg":"upstream roundtrip",
"upstream":"11.11.111.11:3000",
"request":{
"remote_addr":"000.00.000.000:10295",
"proto":"HTTP/2.0",
"method":"GET",
"host":"sub1.example.com",
"uri":"/",
"headers":{},
"tls":{
"resumed":false,
"version":772,
"cipher_suite":4865,
"proto":"h2",
"proto_mutual":true,
"server_name":"sub1.example.com"
}
},
"duration":2.001191542,
"error":"dial tcp 11.11.111.11:3000: i/o timeout"
}
{
"level":"debug",
"ts":1636466502.6490903,
"logger":"http.handlers.reverse_proxy",
"msg":"upstream roundtrip",
"upstream":"22.22.222.222:3000",
"request":{
"remote_addr":"000.00.000.000:10295",
"proto":"HTTP/2.0",
"method":"GET",
"host":"sub1.example.com",
"uri":"/",
"headers":{},
"tls":{
"resumed":false,
"version":772,
"cipher_suite":4865,
"proto":"h2",
"proto_mutual":true,
"server_name":"sub1.example.com"
}
},
"headers":{
"Content-Type":[
"text/html; charset=UTF-8"
],
"X-Request-Id":[
"4e47d9a6-6a3a-4d54-a798-6bfd35977c81"
],
"X-Runtime":[
"0.001762"
],
"Content-Length":[
"1564"
]
},
"status":200
}
Here is one where the proxy needs to try to offline nodes before moving on to the third. What confuses me here is that the first upstream node with IP 22.22.222.22
has 3 log entries, each of them with 2 seconds between them:
{
"level":"debug",
"ts":1636467323.549891,
"logger":"http.handlers.reverse_proxy",
"msg":"upstream roundtrip",
"upstream":"22.22.222.22:3000",
"request":{
"remote_addr":"000.00.000.000:31768",
"proto":"HTTP/2.0",
"method":"GET",
"host":"sub1.example.com",
"uri":"/",
"headers":{},
"tls":{
"resumed":false,
"version":772,
"cipher_suite":4865,
"proto":"h2",
"proto_mutual":true,
"server_name":"sub1.example.com"
}
},
"duration":2.000809116,
"error":"dial tcp 22.22.222.22:3000: i/o timeout"
}
{
"level":"debug",
"ts":1636467325.8050127,
"logger":"http.handlers.reverse_proxy",
"msg":"upstream roundtrip",
"upstream":"22.22.222.22:3000",
"request":{
"remote_addr":"000.00.000.000:31768",
"proto":"HTTP/2.0",
"method":"GET",
"host":"sub1.example.com",
"uri":"/",
"headers":{},
"tls":{
"resumed":false,
"version":772,
"cipher_suite":4865,
"proto":"h2",
"proto_mutual":true,
"server_name":"sub1.example.com"
}
},
"duration":2.000451613,
"error":"dial tcp 22.22.222.22:3000: i/o timeout"
}
{
"level":"debug",
"ts":1636467328.0595753,
"logger":"http.handlers.reverse_proxy",
"msg":"upstream roundtrip",
"upstream":"22.22.222.22:3000",
"request":{
"remote_addr":"000.00.000.000:31768",
"proto":"HTTP/2.0",
"method":"GET",
"host":"sub1.example.com",
"uri":"/",
"headers":{},
"tls":{
"resumed":false,
"version":772,
"cipher_suite":4865,
"proto":"h2",
"proto_mutual":true,
"server_name":"sub1.example.com"
}
},
"duration":2.000397228,
"error":"dial tcp 22.22.222.22:3000: i/o timeout"
}
{
"level":"debug",
"ts":1636467330.3136094,
"logger":"http.handlers.reverse_proxy",
"msg":"upstream roundtrip",
"upstream":"33.333.333.33:3000",
"request":{
"remote_addr":"000.00.000.000:31768",
"proto":"HTTP/2.0",
"method":"GET",
"host":"sub1.example.com",
"uri":"/",
"headers":{},
"tls":{
"resumed":false,
"version":772,
"cipher_suite":4865,
"proto":"h2",
"proto_mutual":true,
"server_name":"sub1.example.com"
}
},
"duration":2.000392293,
"error":"dial tcp 33.333.333.33:3000: i/o timeout"
}
{
"level":"debug",
"ts":1636467330.571421,
"logger":"http.handlers.reverse_proxy",
"msg":"upstream roundtrip",
"upstream":"23.88.117.149:3000",
"request":{},
"tls":{
"resumed":false,
"version":772,
"cipher_suite":4865,
"proto":"h2",
"proto_mutual":true,
"server_name":"sub1.example.com"
}
},
"headers":{
"X-Xss-Protection":[
"1; mode=block"
],
"X-Content-Type-Options":[
"nosniff"
],
"Content-Type":[
"text/html"
],
"X-Runtime":[
"0.002176"
],
"X-Frame-Options":[
"SAMEORIGIN"
],
"X-Download-Options":[
"noopen"
],
"X-Permitted-Cross-Domain-Policies":[
"none"
],
"Referrer-Policy":[
"strict-origin-when-cross-origin"
],
"Cache-Control":[
"no-cache"
],
"X-Request-Id":[
"0b24f050-d8c0-4868-a090-b3f5c981bb81"
]
},
"status":200
}
And the last is one where the request times out after 15 minutes. The 15 minute duration of timed out requests seems to be consistant:
{
"level":"debug",
"ts":1636472779.2905798,
"logger":"http.handlers.reverse_proxy",
"msg":"upstream roundtrip",
"upstream":"11.11.111.11:3000",
"request":{
"remote_addr":"000.00.000.000:24845",
"proto":"HTTP/2.0",
"method":"GET",
"host":"sub1.example.com",
"uri":"/",
"headers":{},
"tls":{
"resumed":false,
"version":772,
"cipher_suite":4865,
"proto":"h2",
"proto_mutual":true,
"server_name":"sub1.example.com"
}
},
"duration":946.405977244,
"error":"dial tcp 11.11.111.11:3000: i/o timeout"
}
{
"level":"error",
"ts":1636472779.2957606,
"logger":"http.log.error",
"msg":"dial tcp 11.11.111.11:3000: i/o timeout",
"request":{
"remote_addr":"000.00.000.000:24845",
"proto":"HTTP/2.0",
"method":"GET",
"host":"sub1.example.com",
"uri":"/",
"headers":{},
"tls":{
"resumed":false,
"version":772,
"cipher_suite":4865,
"proto":"h2",
"proto_mutual":true,
"server_name":"sub1.example.com"
}
},
"duration":946.411582797,
"status":502,
"err_id":"d0ihj6i7b",
"err_trace":"reverseproxy.statusError (reverseproxy.go:858)"
}