Caddy docker deployment is not reverse proxying docker container to the outside of docker

1. The problem I’m having:

I am trying to reverse proxy a web server running inside a docker container in my docker network (which has my caddy docker container attatched to it) at “https://172.23.0.3:47990” to the ip of my host at “https://10.0.0.8:100”. Using the command “docker exec -ti container1 ping container2” I am able get caddy to ping the container I am trying to reverse proxy to. Also the reason why I can’t just expose the ports on the docker container is because im deploying this container using kasm workspaces which doesnt let me expose ports to the host.

2. Error messages and/or full log output:

caddy-caddy-1  | {"level":"info","ts":1730642999.311998,"logger":"tls.obtain","msg":"lock acquired","identifier":"10.0.0.8"}
caddy-caddy-1  | {"level":"info","ts":1730642999.3120174,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"10.0.0.8"}
caddy-caddy-1  | {"level":"info","ts":1730642999.3124335,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"10.0.0.8","issuer":"local"}
caddy-caddy-1  | {"level":"info","ts":1730642999.3124585,"logger":"tls.obtain","msg":"releasing lock","identifier":"10.0.0.8"}
caddy-caddy-1  | {"level":"warn","ts":1730642999.3125658,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [10.0.0.8]: no OCSP server specified in certificate","identifiers":["10.0.0.8"]}
caddy-caddy-1  | {"level":"info","ts":1730642999.3151202,"logger":"admin","msg":"stopped previous server","address":"localhost:2019"}
caddy-caddy-1  | {"level":"info","ts":1730643038.3380826,"logger":"admin.api","msg":"received request","method":"POST","host":"localhost:2019","uri":"/load","remote_ip":"127.0.0.1","remote_port":"53396","headers":{"Accept-Encoding":["gzip"],"Content-Length":["288"],"Content-Type":["application/json"],"Origin":["http://localhost:2019"],"User-Agent":["Go-http-client/1.1"]}}
caddy-caddy-1  | {"level":"info","ts":1730643038.3381233,"msg":"config is unchanged"}
caddy-caddy-1  | {"level":"info","ts":1730643038.3381252,"logger":"admin.api","msg":"load complete"}
caddy-caddy-1  | {"level":"info","ts":1730644852.0914085,"logger":"admin.api","msg":"received request","method":"POST","host":"localhost:2019","uri":"/load","remote_ip":"127.0.0.1","remote_port":"39484","headers":{"Accept-Encoding":["gzip"],"Content-Length":["288"],"Content-Type":["application/json"],"Origin":["http://localhost:2019"],"User-Agent":["Go-http-client/1.1"]}}
caddy-caddy-1  | {"level":"info","ts":1730644852.0914505,"msg":"config is unchanged"}
caddy-caddy-1  | {"level":"info","ts":1730644852.0914521,"logger":"admin.api","msg":"load complete"}

3. Caddy version:

CADDY_VERSION=v2.8.4

4. How I installed and ran Caddy:

a. System environment:

Deployed in a proxmox server on the host inside docker

c. Service/unit/compose file:

version: "3.7"
networks:
  caddy:
services:
  caddy:
    image: caddy:latest
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - $PWD/Caddyfile:/etc/caddy/Caddyfile
      - $PWD/site:/srv
      - ./caddy_data:/data
      - ./caddy_config:/config
    networks:
      - caddy

volumes:
  caddy_data:
    external: true
  caddy_config:

d. My complete Caddy config:

{
  email mymail@example.com
}

 https://10.0.0.8:100 {
        reverse_proxy https://172.23.0.3:47990
}

5. Links to relevant resources:

Im also pretty new to caddy and reverse proxying in general so let me know if im doing something horribly wrong

Hello!

I think that you’re referring to ports 80 and 443 here. Operating under that assumption…

I believe you need to specify your custom port in your compose file, otherwise Docker will not expose the container’s port to the host:

    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
      - "100:100"

More about this in the Docker docs

What you seemed to have said partially worked, when I fixed my caddyfile, restarted the container, and then headed to https://10.0.0.8:100 it shows this:


It might be worth mentioning that I didn’t port forward caddy, I don’t really know whether I need to or not
Here are some more logs if you need them:

caddy-caddy-1  | {"level":"info","ts":1730755689.8046045,"msg":"shutdown complete","signal":"SIGTERM","exit_code":0}
caddy-caddy-1  | {"level":"info","ts":1730755690.0724163,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
caddy-caddy-1  | {"level":"info","ts":1730755690.0728266,"msg":"adapted config to JSON","adapter":"caddyfile"}
caddy-caddy-1  | {"level":"info","ts":1730755690.0730834,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//127.0.0.1:2019","//localhost:2019","//[::1]:2019"]}
caddy-caddy-1  | {"level":"info","ts":1730755690.0731266,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
caddy-caddy-1  | {"level":"info","ts":1730755690.0732243,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000253e00"}
caddy-caddy-1  | {"level":"info","ts":1730755690.0733347,"logger":"http","msg":"enabling HTTP/3 listener","addr":":100"}
caddy-caddy-1  | {"level":"info","ts":1730755690.073395,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
caddy-caddy-1  | {"level":"info","ts":1730755690.0734048,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
caddy-caddy-1  | {"level":"info","ts":1730755690.0734072,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["10.0.0.8"]}
caddy-caddy-1  | {"level":"warn","ts":1730755690.073497,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [10.0.0.8]: no OCSP server specified in certificate","identifiers":["10.0.0.8"]}
caddy-caddy-1  | {"level":"info","ts":1730755690.0735211,"logger":"pki.ca.local","msg":"root certificate is already trusted by system","path":"storage:pki/authorities/local/root.crt"}
caddy-caddy-1  | {"level":"info","ts":1730755690.073598,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
caddy-caddy-1  | {"level":"info","ts":1730755690.0736003,"msg":"serving initial configuration"}
caddy-caddy-1  | {"level":"info","ts":1730755690.0743985,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/data/caddy","instance":"d85fb206-f849-4ff9-b759-19cf1efa2ff5","try_again":1730842090.074398,"try_again_in":86399.999999851}
caddy-caddy-1  | {"level":"info","ts":1730755690.0744264,"logger":"tls","msg":"finished cleaning storage units"}```

@Vortex_Norman what’s the relevance of port 100? Why do you think you want to use that port?

Similarly, what’s the relevance of port 47990?

Your post does not clearly explain what you’re trying to do. You didn’t show your entire setup, you only showed the Caddy part of your Docker-Compose stack. Show everything.

1 Like

Sorry for not explaining properly, but I need to expose port 47990 for a game streaming service called sunlight ( I want to be able to do a bit of gaming alongside my server ) that is currently in a docker container, and that docker container is being deployed by a service called kasm workspaces (read more about what kasm is here —> https://kasmweb.com). The reason why I’m using kasm workspaces to provision the container is for web access to a desktop as well as good latency streaming access from sunlight as well. Now normally you would be able to expose the docker port to be able to access it, but kasm workspaces doesn’t have that functionality since it’s main idea is to just be able to easily manage multiple of these containers and provision them with new ip addresses depending on how many containers are in its docker network. But by assigning a container provisioned in kasm to its own seperate docker network, I get the same ip address every time when the container is made. Now port 100 is completely random and I just need literally any port that I can expose to the host that I can use.

Are you sure it’s HTTP? Caddy’s standard distribution only has an HTTP server. If your game server is raw TCP or UDP, then you’d need GitHub - mholt/caddy-l4: Layer 4 (TCP/UDP) app for Caddy instead.

Using kasm seems like an unnecessary complication. Simplify things to start.

1 Like

Yeah I think your right because I found another game streaming service called steam headless specifically built for gaming, so I don’t think I need to use kasm workspaces or a reverse proxy. Kasm workspaces documentation also notes that I can assign a docker container to an IPvlan docker network which also can solve my issue. Thanks for helping me anyways though!

I also think your right when you said my server uses raw UDP, so I might try to experiment with that plugin for caddy when I get the chance

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