Caddy Reverse Proxy Getting 502

1. Caddy version:

v2.6.2 h1:wKoFIxpmOJLGl3QXoo6PNbYvGW4xLEgo32GPBEjWL8o=

2. How I installed, and run Caddy:

a. System environment:

PRETTY_NAME=“Debian GNU/Linux 11 (bullseye)”
NAME=“Debian GNU/Linux”
VERSION_ID=“11”
VERSION=“11 (bullseye)”
VERSION_CODENAME=bullseye
ID=debian
Linux pi3 5.15.84-v8+ #1610 SMP PREEMPT Mon Dec 19 18:54:50 GMT 2022 aarch64 GNU/Linux

My hosts file:

IP Address Host name
127.0.0.1 caddy.local
127.0.0.1 api1.caddy.local
127.0.0.1 api2.caddy.local

b. Command:

docker-compose up

c. Service/unit/compose file:

networks:
  backend:
    name: caddy-backend

services:
  api1:
    image: chentex/go-rest-api
    container_name: api1
    ports:
      - "8081:8080"
    networks:
      - backend

  api2:
    image: chentex/go-rest-api
    container_name: api2
    ports:
      - "8082:8080"
    networks:
      - backend

  caddy-proxy:
    image: caddy:latest
    restart: unless-stopped
    container_name: caddy-proxy
    ports:
      - "80:80"
      - "443:443"
    networks:
      - backend
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
      - ./caddy/site:/srv
      - ./caddy/caddy_data:/data
      - ./caddy/caddy_config:/config

d. My complete Caddy config:

(common) {
        header /* {
                -Server
        }
}

http://localhost, http://caddy.local {
    file_server
}

http://api1.caddy.local {
        reverse_proxy /* api1:8081 {
        }
}

http://api2.caddy.local {
        reverse_proxy api2:8082
}

3. The problem I’m having:

I have two REST services, one on port 8081, the other on 8082.
I would like to access then with sub-domains api1 and api2.
As I understand it I have to setup a reverse proxy. Please check my Caddyfile

My issue is if I make a request to http://api1.caddy.local or http://api2.caddy.local I get 502 Bad Gateway.

4. Error messages and/or full log output:

caddy-proxy  | {"level":"info","ts":1674902635.870023,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":"caddyfile"}
caddy-proxy  | {"level":"warn","ts":1674902635.8730998,"msg":"Caddyfile input is not formatted; run the 'caddy fmt' command to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":2}
caddy-proxy  | {"level":"info","ts":1674902635.8749397,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
caddy-proxy  | {"level":"warn","ts":1674902635.8753066,"logger":"http","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server","server_name":"srv0","http_port":80}
caddy-proxy  | {"level":"info","ts":1674902635.8755896,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000250d20"}
caddy-proxy  | {"level":"info","ts":1674902635.8760586,"logger":"tls","msg":"cleaning storage unit","description":"FileStorage:/data/caddy"}
caddy-proxy  | {"level":"info","ts":1674902635.8763683,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
caddy-proxy  | {"level":"info","ts":1674902635.8827271,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
caddy-proxy  | {"level":"info","ts":1674902635.8827903,"msg":"serving initial configuration"}
caddy-proxy  | {"level":"info","ts":1674902635.9458852,"logger":"tls","msg":"finished cleaning storage units"}
caddy-proxy  | {"level":"error","ts":1674902639.480717,"logger":"http.log.error","msg":"dial tcp 172.19.0.3:8081: connect: connection refused","request":{"remote_ip":"172.19.0.1","remote_port":"58498","proto":"HTTP/1.1","method":"GET","host":"api1.caddy.local","uri":"/","headers":{"Accept-Encoding":["gzip, deflate"],"Connection":["keep-alive"],"Sec-Gpc":["1"],"Pragma":["no-cache"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"],"Accept-Language":["en-US,en;q=0.5"],"Cache-Control":["no-cache"],"Dnt":["1"],"Upgrade-Insecure-Requests":["1"]}},"duration":0.002307659,"status":502,"err_id":"6xwnbfs24","err_trace":"reverseproxy.statusError (reverseproxy.go:1272)"}
caddy-proxy  | {"level":"error","ts":1674902716.4052043,"logger":"http.log.error","msg":"dial tcp 172.19.0.2:8082: connect: connection refused","request":{"remote_ip":"172.19.0.1","remote_port":"58504","proto":"HTTP/1.1","method":"GET","host":"api2.caddy.local","uri":"/","headers":{"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"],"Accept-Language":["en-US,en;q=0.5"],"Accept-Encoding":["gzip, deflate"],"Dnt":["1"],"Connection":["keep-alive"],"Cache-Control":["no-cache"],"Upgrade-Insecure-Requests":["1"],"Sec-Gpc":["1"],"Pragma":["no-cache"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0"]}},"duration":0.002790252,"status":502,"err_id":"rz7dwttn7","err_trace":"reverseproxy.statusError (reverseproxy.go:1272)"}

5. What I already tried:

I’ve tried adding logger to the reverse_proxy block, tried different path and name matchers.
In my case everything is http, but I also tried services to listen on https.

6. Links to relevant resources:

After posting here, I realized my error.
I am mapping ports 8081:8080 for api1 container and 8082:8080 for api2 container.
But the proxying happens inside the docker network so the correct Caddyfile would be:

http://localhost, http://caddy.local {
    file_server
}

http://api1.caddy.local {
        reverse_proxy /* api1:8080 {
        }
}

http://api2.caddy.local {
        reverse_proxy api2:8080
}

Yep, that’s right :+1:

You don’t need to bind ports for those containers to the host (so you can remove their ports mappings. Caddy will reach them through the Docker network.

You don’t need this. There’s no benefit to removing the Server header. It doesn’t increase security in any way.

You don’t need /* and the { } braces here.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.