lucaslorentz / caddy-docker-proxy

Caddy as a reverse proxy for Docker
MIT License
2.86k stars 168 forks source link

How to make requests to reverse proxy inside docker network? #543

Closed f1amy closed 11 months ago

f1amy commented 11 months ago

I added caddy docker proxy to my docker-compose file and configured services with labels to be accessible via proxy. It is working great when making requests from the host system (I use localhost as base domain).

The question is, how to make requests to my services from inside the docker network? For a hypothetical service A with configured caddy-docker-proxy label caddy: https://service-a.something.localhost, if I'm inside hypothetical service B, how do I make a request like this: curl -X GET https://service-a.something.localhost/something?

francislavoie commented 11 months ago

You can add http://caddy as a site address (comma separated) to allow requests from another container.

If you add that, depending on the level of paranoia, you may want to reject requests with that hostname from non-private IP ranges.

f1amy commented 11 months ago

@francislavoie, I don't quite understand where should I add this site address, let me add an example:

services:
  proxy:
    image: lucaslorentz/caddy-docker-proxy:alpine
    ports:
      - 80
    environment:
      - CADDY_INGRESS_NETWORKS=docker-proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - docker-proxy

  service-a:
    image: nginx:alpine
    labels:
      caddy: http://*.service-a.localhost
      caddy.reverse_proxy: "{{upstreams 80}}"
    networks:
      - docker-proxy

  service-b:
    image: nginx:alpine
    labels:
      caddy: http://service-b.localhost
      caddy.reverse_proxy: "{{upstreams 80}}"
    networks:
      - docker-proxy

networks:
  docker-proxy:

If I'm on host, I can curl -X GET http://anything.service-a.localhost. But if I'm inside service-b, I get unknown host error.

francislavoie commented 11 months ago

caddy: http://*.service-a.localhost becomes caddy: "http://*.service-a.localhost, http://proxy" and then make your services request http://proxy/something (where proxy is the name of your Caddy docker service)

The problem you have is that localhost while inside a container means "this same container", so you can't use localhost to route between container.

f1amy commented 11 months ago

@francislavoie Thanks for the reply, using http://caddy does seem to work for one service, however, this does not solve my problem entirely.

I want to be able to use dynamic hosts to call the service that I need.

The example:

services:
  proxy:
    image: lucaslorentz/caddy-docker-proxy
    ports:
      - 80:80
    environment:
      - CADDY_INGRESS_NETWORKS=caddy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - caddy_data:/data
    networks:
      - caddy

  service-a:
    image: nginx:alpine
    ports:
      - 8081:80
    networks:
      - caddy
    labels:
      caddy: http://*.service-a.localhost, http://*.service-a.proxy
      caddy.reverse_proxy: "{{upstreams 80}}"

  service-b:
    image: nginx:alpine
    ports:
      - 8082:80
    networks:
      - caddy
    labels:
      caddy: http://service-b.localhost, http://service-b.proxy
      caddy.reverse_proxy: "{{upstreams 80}}"

volumes:
  caddy_data:

networks:
  caddy:

Doing curl -I http://service-b.proxy from service-a results in:

curl: (6) Could not resolve host: service-b.proxy

I don't know how to make it work.

francislavoie commented 11 months ago

You'd need to add extra_hosts to your proxy service for Docker to know how to route that hostname. Unfortunately Docker doesn't offer a way to do wildcard aliases https://github.com/moby/moby/issues/43442 https://github.com/moby/moby/pull/43444

f1amy commented 11 months ago

Oh, that's a shame. I had the feeling that this is not possible without workarounds.

Speaking of workarounds, will caddy docker proxy respect X-Forwarded-Host header to do dynamic routing?

Like curl -X GET http://proxy -H "X-Forwarded-Host: any-wildcard.service-a.caddy"?

Anyway, this issue could be closed I guess.

francislavoie commented 11 months ago

No, only Host. The X-Forwarded-Host header is an application layer thing. Host is HTTP layer.

FWIW your other option is you can run a DNS server in your stack like dnsmasq or CoreDNS which could get around those Docker DNS limitations.

annas-atchia-bocasay commented 7 months ago

@f1amy did you managed to solve this?

francislavoie commented 7 months ago

@annas-atchia-bocasay open a new issue if you need help.