Website and Websocket(s) on the same port with Caddy!

Caddy server (https://github.com/mholt/caddy)

I’m using WebSockets for almost every project that needs communication. That has many reasons even though I like working with raw TCP connections. My 2019’s most important reason is usability via the web and passing through proxies, since proxies are a big issue because I’m behind one at work.

However, the problem is that WebSockets can only be connected to over most proxies via ports 80 (HTTP) or 443 (HTTPS – encrypted HTTP). That means my web server and my WebSocket(s) have to run on the same port which was not working out with my then-used web server software.

Because I like to reinvent the wheel, I wrote my own HTTPS & WebSocket sharing / proxying web server.

But, luckily, that day came:

On one weekly meeting at Freifunk Bremen, an open wifi providing nonprofit association in Bremen Germany, I was caught by a friend developing this monstrosity. He then recommended Caddy server, a web server and much more, for me.

But long, long talk short: Caddy does incredibly much stuff, incredibly easy.
It also handles my use-case well, in which there are more than one service on a port.

Caddy can proxy a path to a websocket, which means I can provide many services, written in many different languages, etc., and don’t have to configure HTTPS for any of these, because Caddy is the proxy for all these services, providing HTTPS with one click! 

Example:

win311.xyz
{
proxy /ws 127.0.0.1:12345
{
websocket
}
}

It’s that easy! But what does it do?

win311.xyz {

Opens a Caddy configuration block with “{” to configure incoming connections to “win311.xyz”.

  proxy /ws 127.0.0.1:12345 {

The path “win311.xyz/ws” is proxied to the local WebSocket server on port 12345 (could also be a unix socket, if you want). That WebSocket server is just plain HTTP, unencrypted, because Caddy encrypts the critical data path: After it left your trusted environment: the Server. A Caddy configuration block is opened with”{“.

    websocket
}
}

The proxy has to treat the connection as a websocket connection. (Leave the configuration block empty if this should be a standard HTTP proxying.) Also, both Caddy configuration blocks have been closed (for the domain and the proxy blocks).

You can easily create more proxies by just adding another Caddy configuration “proxy” block like above, but for another path!

There is so much Caddy can do!