How to use Caddy to proxy other Caddy containers?

1. The problem I’m having:

I have two dockerized hobby projects which both use Caddy.
I’d like to host these all on one VPS to keep my costs low. They work when running them alone, but both use port 443 so can’t run them at the same time.
I was thinking of adding one “global/proxy” Caddy container to recieve :443 traffic and proxy the requests based on domain names to correct “hobby/sub-” Caddy containers.

Something like this:

domain1.com {
  ??? hobby_caddy1:8443
}

domain2.com {
  ??? hobby_caddy2:9443
}

I’d like to have the hobby projects’ Caddy container to handle the tls/cert and for the “global” Caddy to just proxy.

I’m not sure how to achieve this, e.g. how to set up this proxy Caddy or is there a better solution?

2. Error messages and/or full log output:

(no error yet, just want to know how to do it)

3. Caddy version:

v2.7.5

4. How I installed and ran Caddy:

Using official caddy image and running with docker-compose up.

a. System environment:

I’m using docker compose on a Ubuntu VPS

How my hobby projects look:

# docker-compose.yml
version: "3.8"
services:
  hobby_app:
    expose: 9000
    networks:
      - hobby_network
     ...
  hobby_caddy:
    image: caddy
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./caddy/data/:/data/
      - ./caddy/config/:/config/
      - ./Caddyfile:/etc/caddy/Caddyfile
    networks: 
      - hobby_network

b. Command:

I run the project with simple

docker-compose up -d

d. My complete Caddy config:

My hobby projects’ Caddyfile

  domain1.com {
	reverse_proxy hobby_app:9000
}

For simplicity, I’ll call them “front” and “back” Caddy instances.

If you want your back instances to manage TLS, your front instance must do TCP-layer proxying such that it doesn’t terminate TLS. This means you can’t use vanilla Caddy to do this, you’d need to use GitHub - mholt/caddy-l4: Layer 4 (TCP/UDP) app for Caddy (or any other layer4 proxy) to transparently proxy the TCP traffic. You could use TLS-SNI matching to split the traffic between different backend servers if necessary.

Simpler is to have the front instance terminate TLS, then you can proxy over HTTP to the back instances which are listening for HTTP (not HTTPS). You’d use http://domain1.com as your site address on your back instances for that. This approach is fine as long as your back instances are not publicly accessible and only accessible through your front instance (with a VPN or tunnel of somekind).

More complex is using mTLS (mutual TLS) between your front and back instances so you do HTTPS between them (instead of HTTP in my previous paragraph). This is complex to set up though. See Caddy reverse proxy + Nextcloud + Collabora + Vaultwarden with local HTTPS which covers how this is set up (you can ignore the Nextcloud-specific parts of that article, focusing on mTLS stuff).

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