Websocket Proxy (Phoscon App) - Caddy as NGINX alternative

Hello friends!

I have been using Caddy for some time now and would like to automate my home. For this I use the ConBee II, which maybe some of you know.

On port 8080 a normal HTTP server is running, on port 8081 a websocket server.

I have already found the following NGINX configuration, how would the same configuration (the websocket upgrade proxy part) for Caddy 2 look like?

    location ~ (/.*) {
    set $p 8080;
    if ($http_upgrade = "websocket") {
        set $p 8081;
    }
    proxy_pass http://192.168.1.10:$p$1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header X-Forwarded-Proto $scheme;
}

Thanks a lot.

Tobias

Should be as simple as this:

@websockets {
	header Connection *Upgrade*
	header Upgrade    websocket
}
reverse_proxy @websockets 192.168.1.10:8081

reverse_proxy 192.168.1.10:8080

Oh, wow - easy! That’s why I love caddy.

Thank you @francislavoie :sunglasses:

1 Like

One more question:

I’m using caddy as a docker container. The Phoscon App now tries to access the internal docker ip 172.18.0.4. Is there any chance to rewrite this to the request (proxied) host / ip?

I don’t understand the question. I know nothing about Phoscon, so you’ll need to elaborate.

Instead of accessing with the requested adress, the internal docker ip of the proxied container is shown. Is there any possibility to rewrite this?

That just sounds like a misconfiguration of that app. You should configure it with the actual domain name from which it’s accessible.

This is basically the same problem as described in the below article, except that it’s the hostname instead of the path, but the explanation still applies:

Fixed this @francislavoie. Sorry, this was an problem with Phoscon.

I always get this error in dev console:

WebSocket connection to 'wss://phoscon.lan:8081/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED 

Config:

https://phoscon.lan {
tls internal

@websockets {
    header Connection *Upgrade*
    header Upgrade    websocket
}
reverse_proxy @websockets http://deconz:8081

reverse_proxy http://deconz:8080

}

Any ideas? :confused: Sorry.

Caddy is listening on ports 80 and 443, but your browser is trying to connect on port 8081. Is there configuration to change the websocket port to 443 (or omit the port, because default for wss:// is 443)? Port 8081 is what Caddy proxies to.

Yes, I can use the Phoscon Docker image to set the port to 443. The websocket connection will then be established. Caddy and the Phoscon app are in a docker network (realized via docker-compose).

So far so good, but I don’t really understand why another port doesn’t work? I would have thought that the port is only relevant for the proxy. This means in reverse that I can never adjust the incoming WSS port? (The nginx config above works fine with an other port)

I was suggesting this:

Browser -> HTTPS (port 443) -> Docker -> Caddy -> deconz:8080
Browser -> WSS (port 443) -> Docker -> Caddy -> deconz:8081

To do this, the browser would need to attempt to connect on port 443, so the app would need to tell the browser that the websocket port to use is 443 (or just omit it because like I said, default for wss:// is 443), so it would try to connect to wss://phoscon.lan instead.

You could make Caddy listen on another port as well if this is easier for you, but it means you’d need to configure the Caddy container to also publish that port, and if you mean to access it from outside your network, port forward that as well.

https://phoscon.lan {
	tls internal
	reverse_proxy 192.168.1.10:8080
}

https://phoscon.lan:8081 {
	tls internal
	reverse_proxy 192.168.1.10:8081
}

But :man_shrugging: it’s up to you to choose which option is best for you.