Reverse proxy with custom certs on front and self signed on backend

1. Output of caddy version:

v2.5.2 h1:eCJdLyEyAGzuQTa5Mh3gETnYWDClo1LjtQm2q9RNZrs= via the official Docker container

2. How I run Caddy:

Official Docker image from here: https://hub.docker.com/_/caddy

a. System environment:

Docker on Debian 11

b. Command:

caddy run --config /etc/caddy/Caddyfile --adapter caddyfile

c. Service/unit/compose file:

version: "3.7"

services:
  caddy:
    image: caddy:<version>
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - $PWD/Caddyfile:/etc/caddy/Caddyfile
      - $PWD/site:/srv
      - caddy_data:/data
      - caddy_config:/config

volumes:
  caddy_data:
    external: true
  caddy_config:

d. My complete Caddy config:

https://myapp.localdomain {
    reverse_proxy 192.168.10.5:8443
    tls /etc/caddy/certs/localdomain.crt /etc/caddy/certs/localdomain.key
    transport http {
      tls_insecure_skip_verify
   }
}

3. The problem I’m having:

When using a basic config to the HTTP port in the app and my custom certificate everything works.

https://myapp.localdomain {
    reverse_proxy 192.168.10.5:8000
    tls /etc/caddy/certs/localdomain.crt /etc/caddy/certs/localdomain.key
}

However when I try to then proxy to the HTTPS port on the backend which has a self signed cert, ‘caddy verify’ tells me unrecognized directive: transport and subsequently Caddy will not start. I can indeed connect to 192.168.10.5:8443 manually, so the service is alive and working and showing its self signed cert.

4. Error messages and/or full log output:

/etc/caddy # caddy validate
2022/07/31 16:26:44.091 INFO    using adjacent Caddyfile
validate: adapting config using caddyfile: Caddyfile:52: unrecognized directive: transport

5. What I already tried:

I have tried many multiple permutations based on forums posts. The docs indicate my configuration is correct. https://caddyserver.com/docs/caddyfile/directives/reverse_proxy#transports I have tried with both with and without the ‘tls’ directive within the transport section though without seems adequate as the docs state " * tls uses HTTPS with the backend. This will be enabled automatically if you specify backends using the https:// scheme or port :443, or if any of the below tls_* options are configured.

Also variations on this

https://myapp.localdomain {
    reverse_proxy 192.168.10.5:8443 {
    tls /etc/caddy/certs/localdomain.crt /etc/caddy/certs/localdomain.key
    transport http {
      tls_insecure_skip_verify
   }
  }
}

or

https://myapp.localdomain {
    tls /etc/caddy/certs/localdomain.crt /etc/caddy/certs/localdomain.key
    reverse_proxy 192.168.10.5:8443 {
    transport http {
      tls_insecure_skip_verify
   }
  }
}

This instead gives the error validate: decoding config: unexpected end of JSON input.

Inspired by this:https://pydio.com/en/docs/kb/deployment/running-cells-behind-caddy2-reverse-proxy

6. Links to relevant resources:

Hi :slight_smile:

The transport block needs to be within reverse_proxy, just like you tried already:


Also, your /etc/caddy/certs/* you are using in

doesn’t seem to be bind-mounted in

Are you sure the configs you shared are the ones you use locally?

Also consider using . instead of $PWD for your volumes, for example ./site:/srv.

You could also try recreating the caddy container (docker-compose down & docker-compose up). It is pretty unlikely this will change anything, but might be worth a try anyway :woman_shrugging:

1 Like

You gave me a hint… what fixed this was caddy fmt. Apparently it super cares how the curly brackets are spaced? This worked:

https://myapp.localdomain {
        tls /etc/caddy/certs/localdomain.crt /etc/caddy/certs/localdomain.key
        reverse_proxy 192.168.10.5:8443 {
                transport http {
                        tls_insecure_skip_verify
                }
        }
}

I guess it is picky like YAML.

Yeah, whitespace is important in the Caddyfile; it cares that tokens have at least one space between them: Caddyfile Concepts — Caddy Documentation

The Caddyfile is lexed into tokens before being parsed. Whitespace is significant in the Caddyfile, because tokens are separated by whitespace.

Not even close. Tabs or spaces, or no indents at all, your choice! caddy fmt helps correct common mistakes and makes configs look consistent.

1 Like