Reverse proxy to H2C GRPC

1. Caddy version (caddy version):

Tried both 2.2.1 & 2.3 using the caddy alpine docker

2. How I run Caddy:

start docker:

docker run --rm -it -h node2 --name node2 --network my_net -p 443:443 -v $PWD/Caddyfile:/etc/caddy/Caddyfile -v caddy_data:/data --link node1 caddy:2.3.0-alpine

a. System environment:

docker on fedora linux:

Client: Docker Engine - Community
 Version:           19.03.8
 API version:       1.40
 Go version:        go1.12.17
 Git commit:        afacb8b
 Built:             Wed Mar 11 01:26:01 2020
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
  Version:          19.03.8
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.17
  Git commit:       afacb8b
  Built:            Wed Mar 11 01:24:39 2020
  OS/Arch:          linux/amd64
  Experimental:     false
  Version:          1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
  Version:          0.18.0
  GitCommit:        fec3683

b. Command:

Refer point 2

c. Service/unit/compose file:

Clean docker from caddy repo

d. My complete Caddyfile or JSON config:


log {
    level DEBUG

reverse_proxy {
    to h2c://node1:8008
    transport http {
        versions h2c 2

Also tried:


log {
    level DEBUG

reverse_proxy h2c://node1:8008

3. The problem I’m having:

docker named node1 providing GRPC service on port 8008 without TLS.
the docker also publish the port to localhost and I can query it using:

grpcurl -plaintext -proto main.proto pb.TenantService/List

I can also successfully run it form the caddy docker itself using:

grpcurl -plaintext -proto main.proto node1:8008 pb.TenantService/List

But any attempt to run through the exposed 443 port of caddy fail.

4. Error messages and/or full log output:

# grpcurl -insecure -proto main.proto node2:443 pb.TenantService/List
Failed to dial target host "node2:443": remote error: tls: internal error

caddy itself does not log any error

5. What I already tried:

6. Links to relevant resources:

You’re using localhost, so this will only accept connections that use the host localhost. And also, Caddy will automatically set up localhost with HTTPS (with a local CA to manage the certs).

Change this to :80 instead to ignore the hostname on the request and use HTTP, or use node2 as your hostname and use tls internal to make sure Caddy issues a certificate with the local CA (or set the local_certs global option).

Certain types of messages are hidden under the debug log level. If you enable the debug global option, you might see the TLS handshake error.

1 Like

Thanks @francislavoie,

The domain was the problem.

Here is my working GRPC setup for anyone that is interested

Caddy file

log {
    level INFO

reverse_proxy {
    to h2c://api:8008
    transport http {
        versions h2c 2


version: "3.2"
    container_name: grpc-api
    image: grpc.api.image:v1.2.3
      - 8008:8008
    restart: on-failure
    command: start-whatever
      - api_net
    container_name: caddy
    image: caddy:2.2.1-alpine
      - /tmp:/host
      - ${PWD}/Caddyfile:/etc/caddy/Caddyfile:ro
      - ${PWD}/caddy_data:/data
      - ${PWD}/caddy_config:/config
      - 443:443
    restart: on-failure
      - api_net
    driver: bridge

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