User report: Caddy as loadbalancer on Kubernetes

I have been trying using Caddy as a proxying loadbalancer for an installation of the chat program Mattermost (which uses websockets) and thought I’d share my experience as a user. I’ve been using automatic Letsencrypt. It has been working very well and required very little configuration. Some notes:

  • To reconfigure Caddy, I edit the Caddyfile and rebuild/push a new docker image and delete the pod. This is okay for hobby use.
  • I naively enabled Letsencrypt, did not think to mount storage for certificates and got rate limited for a week on a subdomain. No biggie but it would be useful with some more warnings about this scattered around Letsencrypt documentation.
  • Caddy runs as root, this is not really okay, I’ve been looking at various ways people try to solve this and there does not seem to be a good best practice which works in any OS/Docker regarding this. Hoping this will get some love.
  • I’d want to run a service like Gitlab/Gogs/Gitea in my cluster and have SSH load balanced/proxied.

I also tried using Traefik and K8s Ingress, It was also quite simple to configure (although not nearly as simple as Caddy!) but allows for smoother addition of new services in the kubernetes cluster. However, I ran into problems with websockets which I have yet to solve.

Conclusion: I really like Caddy for its simplicity. However it seems I’ll have to learn HAProxy to get SSH/HTTPS served on the same domain for now!


Thanks for letting us know! Glad you like it.

Why’s this?

From what I could gather I did not see a way to use Caddy as an L4 Proxy, or proxy SSH? I should have said, I want HTTPS and SSH served on the same hostname.

Ah, I see what you mean now. Right, Caddy so far only proxies HTTP. It is possible for someone to write a TCP proxy for Caddy, just hoping someone will do it.

1 Like

It is the responsibility of either the Docker maintainer or the person deploying the container to specify the running user. The accepted method is to include the USER command in the Dockerfile used to build the image. See the Dockerfile reference for more information.

Sure, I agree – It’s just that to use the Caddy Letsencrypt automatically Caddy needs to allocate ports < 1024 which complicates things. This has been discussed at length elsewhere and it’s just the fact that a recommended way of deploying automatic Caddy/Letsencrypt has yet to be discovered and settled upon. I am quite hopeful this will improve as people share best practices and is developed.

1 Like

Hrm, you have a good point.

Thanks for the comprehensive report!

In Kubernetes (or generally Docker) there is no need to bind to a specific (low) port inside the container. In case of k8s you can easily redirect 80/443 to your chosen port through a service object. How about port 2015? :slight_smile:

1 Like

I do not believe that Caddy will attempt to provision a certificate if it thinks it won’t be serving the site on :80 and :443. See Automatic HTTPS docs. If DNS validation is possible, this might be feasible.

1 Like