/home/me/project/caddy
/home/me/project/Caddyfile
No sudo, no config spew across my filesystem. Competition is good, and I had a lot of fun with nginx back in the day but it's too little too late for me. /home/me/project/caddy
/home/me/project/Caddyfile
No sudo, no config spew across my filesystem. Competition is good, and I had a lot of fun with nginx back in the day but it's too little too late for me.It seems like a lot of the hipster tooling dropped those things from the past and honestly it’s so much nicer to have things contained in a single file/dir or at most two. That may be a big reason why kids these days prefer them, honestly.
As for nginx itself it’s actually much better suited for high performance proxies with many conns, imo. I ran some benchmarks and the Go variants (traefik, caddy) eat a lot of memory per conn. Some of that’s unavoidable because of minimum per-goroutine stacks. Now I’m sure they’re better in many ways but I was very impressed with nginxs footprint.
The main difference is in how additional software is handled. Windows, because of its history with mostly third party software being installed, generally installed applications into a folder and that folder contained the application... Mostly. Uninstalling was never as simple as that might imply.
Linux distros had an existing filesystem layout (from Unix) to conform to, so when they started developing package managers, they had to support files all over the place, so they make sure packages include manifests. Want to know where use executable are? Check bin. Superuser.com executables? Check sbin (don't want those cluttering the available utils in the path of regular users). Libs for in libs.
/bin and /usr/bin and the others are holdovers from the long past when disks were small, and recent distros often symlink usr to / so they're different in name only. /usr/local is for admin local modifications that are not handled through a package. /opt is for whatever, and often used for software installed into a contained folder, like in windows.
Just know what bin, sbin, lib, opt and etc are for and most the rest is irrelevant as long as you know how to query the package manager for what files a package provides or as it what package a specific filer belongs to. If you looked I to windows and the various places it puts things I suspect you'd find it at least complicated, if not much more.
Note: what I said may not match the LSB (which someone else usefully posted) perfectly, but for the most part it should work as a simple primer.
I'm pretty annoyed with how many people on HN are shouting in every thread "caddy is soon much better!" and the only material benefit to caddy I can glean from these threads is that it's easier for noobs. Which, to be clear, as far as I can tell, it does a good job of that and will probably win the next decade over nginx for that reason alone, but nginx really isn't that hard to set up, and I'm surprised there isn't so much push back against the pro-caddy narrative. It's just an uphill battle for an application written in golang to be faster than a mature application written in C. Obviously I will continue to use nginx until hard evidence of on-par performance is published, but at the same time I'm more likely to hold out for a competitor written in rust.
Yes but Golang can be fast on almost every aspect too with some simple tricks. The main thing is the goroutine overhead per socket, which impacts reverse proxies indeed.
> but at the same time I'm more likely to hold out for a competitor written in rust.
Rust with Tokio can keep very low overhead theoretically. But language is not everything. For instance Envoy is also quite high per-conn overhead when I checked despite C++. I assume it’s just too many knobs and features.
It is annoying however, that configuration is not standardized across distros.
See also: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html
Fun example from last week, a colleague was trying to try out ACME with a custom ACME server, and configured it. For some reason Caddy was not using it and instead used its own internal cert issuer, even if explicitly told to use the ACME provider as configured. Turns out that if you use the .local domain, Caddy will insist on using its own cert issuer even if there's an ACME provider configured. Does that make sense? Yeah, somewhat, but it's the kind of weird implicit behaviour that makes me mistrust it.
My go-tos are nginx for static stuff, Traefik for dynamic stuff.
With that said, Caddy is pretty rad.
But then it... just works. Try the same with most other web servers/proxies and you're in for a world of pain. Having this much functionality bundled into a single binary is as much a curse as it is a blessing.
That said, having your own little 'Cloudflare Workers' in the form of Nginx Unit with wasm sounds great. Not sure Caddy can do that.
Sure we already have repeatable infrastructure, containers, etc. but I also love the idea of just building and shipping a PHP app binary that includes the webserver. It makes server provisioning even less of a priority, especially if I have reasons to not use serverless or PaaS tools.
Now that single binary deployment requires you to compile the software yourself. Caddy has nice tooling for this but it'd be far more convenient to just drop a dll/so file in the right directory.
Single binary deployments are great if someone else did the compiling for you. If you need to compile yourself it truly does not matter if you need to ship a single binary or a directory or whatever.
https://github.com/Radiergummi/iss-metrics/blob/main/caddy/C...
I was in the same boat as you and wanted to try out what Caddy is capable of. I was immediately convinced. So many features, where you expect them. Consistent configuration language. Environment interpolation, everywhere. Flexible API. It’s really all there.
All of this is more or less doable with nginx, I’ve done it often enough. But read the Caddyfile and tell me this isn’t miles ahead in clarity.
Set the config up with CI/CD and can now just edit the config and git push knowing Caddy will just handle the rest
I don't use docker so I don't care.
So no setting up unattended-upgrades and forgetting about it.
also totally non-standard, apt unattended-upgrades won't be doing that for you.
sure you can do a cronjob, but, non-standard
Caddy really is the most pleasant webserver software I’ve ever used.
In 2024 people are more likely to turn the cloud knob up to pay for throughput (if they need it) and save on dev time with the comparably better dev ex that caddy offers.
This seems like a weird trade off to me.
The "learning tax" is really only paid once with nginx. Once you understand how it works and configured a reasonably end-to-end example with it then you can carry that over to your next project with minimal changes.
I've hosted countless Flask, Django, Rails, etc. apps over the years and very little changes on the nginx side of things. I'd rather learn this tool once and have better runtime performance all the time across all projects.
With that said, the performance difference probably won't be very noticeable for most sites but still, I personally wouldn't want to give in to running a less efficient solution when I know a more efficient solution exists right around corner that requires no application code changes to use -- just a little elbow grease to configure nginx once. This is especially true when nginx has a ~20 year track record of stability and efficiency.
I always find this a weird selling point, TBH.
It's probably a selling point for people who don't already know the existing $FOO.
For me, putting effort into learning the new thing only to use it exactly as the old thing is wasted effort.
I don't know what I gain by moving to the new $FOO, usually.
I would wager the vast majority of Nginx "installs" are running in a container now a days.
The distro doesnt matter and few are provisioning an instance of anything, that's some container orchestration job.
Last week trying to coax nginx to be able to set a CSP nonce in a web apps index.html which apparently meant I would need to custom build Nginx or a custom build a container with a custom built Nginx to install a plug-in to do it. This type of stuff adds up and having a bunch of stuff hidden in Nginx Plus doesn't help either.
I think Nginx is a great piece of software its just that people don't need all its offerings, they just want to host some tiny js and proxy to an API and things like caddy were built for that. The limited throughput doesnt matter when CloudFlare or Cloud front cache most of the things it is serving anyway.
As for the CSP nonce, I'm surprised that there isn't a plugin, but compiling isn't a big deal, just annoying. Alternately NGINX is scriptable or you can do it at the application level as well. If caddy is easier for you or for that use case, then that's great, use it with my blessing.
If someone hooks them up to a man page I think it might level the playing field.
So easy and works on everything