Nginx, caddy 2 or pure Cowboy?

There was an interesting thread about Caddy 2.0 on HN yesterday with a number of people giving it high praise over even nginx.

I wanted to find out what the general consensus of the board was for whether or not to use a reverse proxy in front of your application? Any downsides to doing so? Is it easy enough to use Certbot with Cowboy these days?


We went from using nginx to pure cowboy just to reduce the number of moving parts and have everything in one place, works fine for some time now, less papercuts like having to change upload size, manage request upgrades for WS etc. The only thing that Cowboy can’t is to magically use ports 80 and 443, so we have to use setcap to let Erlang runtime access these ports, each runtime update needs that, but it’s not really a problem since we never do it automatically.

Caddy looks integesting, thanks for the link!

I’m using nginx in front of my applications and have been doing for for the last 5 or 6 years. I’ve tried a few other other options (such as Traefik) but always wound up going back to nginx.

There are lots of great options out there but for me none of them especially stand out as being better than the rest, so I don’t have much motivation to do the rework to switch to something else.

If I wasn’t already using nginx I’d give Caddy a try. It looks good! :slight_smile:


On my new hobby project I use Cowboy standalone.
The certificate issuing is done with lego.
As lego could not access the in use ports 443 & 80, I use a DNS challenge.
Cert renewal is triggered via a recurring task with System.cmd/3 within the OTP application.

By the way as the OTP release does not run as root on my setup, I also port forward 443 & 80 to 4443 & 4080 with the usage of nftables.

So for my little single application I don’t see a benefit in running a reverse proxy in front.
Also to keep the number of moving parts low.

In case you have real high traffic for your application, running a reverse proxy for offsite handling your TLS handshakes could be the reason why to do so.

For my company we currently run Nginx as reverse proxy.
But also thinking about to try Caddy now.
Even if Nginx makes really really no trouble at all.

1 Like

It could use them if you would run it as a root (I highly discourage that). Otherwise you can also try to use systemd's socket activation, however that need a little bit socket hopping as gen_tcp currently do not allow to use already bound file descriptor, it may change in future when gen_tcp will be NIF (socket) based instead of port drivers.

1 Like

I have so far usually used Phoenix/Cowboy behind Nginx in production. The reason being mostly the integration with Let’s Encrypt for the SSL-certificates, and to a lesser extent rewriting e.g. to

I do like the idea of reducing the number of moving parts, though.

1 Like

Nginx just works :man_shrugging:


I am thinking about writing library that would handle that within Cowboy without need for additional layer. Just run and it will work.


I wrote that we use setcap (, it’s a simple solution that works, why would I want to run it as root? :smiley: Running sudo setcap 'cap_net_bind_service=+ep' path/to/beam.smp does the trick.

Yeah, but IMHO still it is better to use socket activation, as this do not need to add additional capabilities to the executables. What is more - you can reduce capabilities and for example disallow listening on any additional ports or stuff like that.

Do note that the last I saw [April 2019], the [Caddy] licensing stance is that you cannot download pre-compiled binaries from their official build servers for commercial purposes without an accompanying commercial license. AFAIK, compiling-it-yourself was always acceptable without a license regardless of usage, and I think based on the quoted passage the binaries on the GitHub release tags are in the clear now. The build server looks like it would be for streamlined installs of binaries with custom plugin payloads.

Beginning today, commercial licenses are no longer required for commercial use of any Caddy binaries. Going forward, only commercial use of our build server (including the download page and requires a subscription: all binaries are licensed the same. Existing customers will be grandfathered in with no changes to their subscription and will be able to keep using the download page as before. Using our download page for non-commercial use will continue to be free. All binaries will be Apache 2 licensed.

For myself, I’ve got no interest in Caddy or Traefik, so I’ll continue to use Nginx, or else direct TLS termination in my IAAS layer’s load-balancing stack via Kubernetes Service/Ingress.

1 Like

Is the distinction here against Saša’s site_encrypt project that your hypothetical implementation would have zero external dependencies, not even certbot?

1 Like

That is the idea. I wasn’t aware of Saša work, so I can check this out and review if I would be able to drop the Certbot dependency and implement ACME protocol directly.


That would be a really cool thing.

FYI Caddy2 does not require any commercial license. It’s 100% open.
It’s a great software. Using it on multiple projects. I have never looked back at Nginx after moving to Caddy, even in its v1 times. v2 is on another level.

1 Like

I’m currently using traefik for proxying domain names to services – traefik mostly because of it’s listening to changes on it’s config files automatically – with caddy behind only for the things, which need a webserver (php / static files). I guess with the caddy 2 I could move to have just caddy do both things.

This is already on the roadmap :slight_smile:
site_encrypt already includes a very basic ACME server (for local debugging and testing), and I’d like to see both the server being expanded and a native client developed. Sadly I can’t find the time for this, so if someone else wants to take a stab, feel free to ping me :slight_smile:


Against my better judgement I made some time and implemented a basic ACME client :slight_smile: It’s very immature, incomplete, and probably buggy, but it works for the basic case (tried it out on my blog). I also went ahead and published the package on hex. You can find the docs here.


I am using traefik, too. I like its Docker support – you can specify labels for Docker containers, then traefik will configure the proxy for them automatically.

With Caddy 2 you get ssl for free out of the box. Nothing to setup, it auto updates as well. It also has live updating, so you don’t have to restart the service to update the config. I have been using it for 3 months now and would recommend it.

1 Like