caddy-docker-proxy icon indicating copy to clipboard operation
caddy-docker-proxy copied to clipboard

[Help] Postgres DB behind caddy-docker-proxy

Open accforgithubtest opened this issue 1 year ago • 7 comments

I am seeking help to get postgres running behind caddy-docker-proxy. Is it possible to host the postgres db behind caddy docker proxy, especially without opening the ports on the docker host ?

I currently have pihole redirecting local.host to the ip address of docker host. Postgres, pihole, caddy-docker-proxy are all set up via docker compose, on the same default bridge network, with ipv6 disabled. This set-up is working for the most part, except for the reverse proxying using caddy-docker-proxy.

I tried using dbeaver to connect to postgres -

  1. Without exposing the host port, using the url - jdbc:postgresql://postgres.local.host/root and get connection refused even when I pass the user credentials on the UI. No logs on both postgres and caddy-docker-proxy container logs.
  2. If I enable the host ports, then I am able to connect via jdbc:postgresql://local.host:5432/root using the user credentials on the UI. This means even though I have added the below labels to postgres container, it doesn't seem to be doing the reverse proxying.

Am i missing any additional labels needed for a database reverse proxying ? TIA to anyone who can share a working docker compose set up for postgres behind caddy-docker-proxy.

services:
  postgres:
    image: postgres:
    # ports:
      # - ${port_host_postgres}:5432
    labels:
      - caddy=postgres.local.host
      - caddy.reverse_proxy={{upstreams 5432}}
    volumes:
    ...
    ...

accforgithubtest avatar Dec 13 '24 01:12 accforgithubtest

Caddy by default is an HTTP(s) (layer 7) server/reverse proxy. As far as I know, postgres doesn't connect via HTTP connection. You would need an additional plugin like caddy-l4, and you should be able to configure it with CDP labels as well. Search CDP issues for "layer 4," "caddy-l4," and "TCP," and you will find some discussions and examples.

lucaslorentz avatar Dec 13 '24 17:12 lucaslorentz

Maybe this is the only discussion where someone claimed to get it working: https://github.com/lucaslorentz/caddy-docker-proxy/issues/236

The main challenge at the moment is that it is impossible to write IP addresses in key of of a docker label because dot means nesting, and we don't support escaping it. But doing it without IP, just with port might work.

lucaslorentz avatar Dec 13 '24 17:12 lucaslorentz

Thank you @lucaslorentz - I will check that discussion out. Appreciate you pointing me in the right direction.

accforgithubtest avatar Dec 13 '24 19:12 accforgithubtest

@accforgithubtest have you make it worked?

rizary avatar Dec 26 '24 11:12 rizary

@Rizary - Not yet unfortunately. I need to upgrade to caddy 2.8.4 according to that discussion, however a different issue with sablier is preventing me from upgrading to 2.8.4.

accforgithubtest avatar Dec 26 '24 18:12 accforgithubtest

I've tried this but failed miserably

Dockerfile (pushed as sandros94/caddy-cache-l4:2.9.1.0 for convenience):

ARG CADDY_VERSION=2.9.1
FROM caddy:${CADDY_VERSION}-builder AS builder

RUN xcaddy build \
    --with github.com/lucaslorentz/caddy-docker-proxy/v2 \
    --with github.com/caddyserver/cache-handler \
    --with github.com/mholt/caddy-l4

FROM caddy:${CADDY_VERSION}-alpine

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

CMD ["caddy", "docker-proxy"]

with the following docker-compose as an example:

name: ssl-caddy-test

services:
  caddy:
    image: sandros94/caddy-cache-l4:2.9.1.0
    restart: unless-stopped
    ports:
      - '80:80'
      - '443:443'
      - '5432:5432'
    environment:
      - CADDY_INGRESS_NETWORKS=caddy
      - CADDY_DOCKER_POLLING_INTERVAL=5s
      - CADDY_DOCKER_SCAN_STOPPED_CONTAINERS=false
    networks:
      - caddy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - './.data:/data'
    labels:
      caddy.email: "[email protected]"

  whoami:
    image: traefik/whoami
    networks:
      - caddy
    labels:
      caddy: whoami.example.com
      caddy.reverse_proxy: "{{upstreams 80}}"
  
  postgres:
    image: postgres:17
    restart: unless-stopped
    networks:
      - caddy
    environment:
      POSTGRES_PASSWORD: postgres
      PGSSLMOD: require
      PGSSLNEGOTIATION: direct
    labels:
      caddy.layer4.:5432.@postgres: "tls sni db.example.com"
      caddy.layer4.:5432.route: "@postgres"
      caddy.layer4.:5432.route.proxy: "{{upstreams 5432}}"
      caddy.layer4.:5432.route.tls.connection_policy.alpn: postgresql

networks:
  caddy:

The Caddyfile gets populated correctly, but if I try to connect to it via psql "postgresql://postgres:[email protected]/postgres?sslnegotiation=direct&sslmode=require" I get

psql: error: connection to server at "db.example.com" (IP Address), port 5432 failed: SSL SYSCALL error: EOF detected

sandros94 avatar Feb 15 '25 16:02 sandros94

I just realized that with the SSL SYSCALL error: EOF detected error that means that it is postgres responding (so proxing does work) but caddy doesn't generate any certificates to use

sandros94 avatar Feb 25 '25 20:02 sandros94