
Switching from Nginx to Caddy - kixpanganiban
https://blog.kixpanganiban.com/switching-from-nginx-to-caddy/
======
dom0
> It would be no exaggeration to say that Caddy, an up-and-coming HTTP/2
> server written in Go that's been gaining a lot of traction, is outright
> witchcraft. Out of the box, it just works. With HTTPS. With very little
> configuration.

It's funny that he goes on to compare the two configuration files, where one
is a bit verbose, but very clear and easy to understand, while the "Caddyfile"
(seriously? xy.conf not good enough anymore?) is four lines that mean
basically nothing without a manual.

Less configuration is not intrinsically better.

~~~
vog
_> It's funny that he goes on to compare the two configuration files, where
one is a bit verbose, but very clear and easy to understand, while the
"Caddyfile" [...] is four lines that mean basically nothing without a manual._

I strongly disagree with this one. In general, I observe that too many super-
configurable tools are essentially putting manual work onto the administrator
that should really be solved in the software itself, where it is solved once
and for all, and can be improved for all at once.

For example, the following line in Caddy:

    
    
        transparent
    

It replaces the following lines in nginx:

    
    
           proxy_set_header   X-Real-IP $remote_addr;
           proxy_set_header   Host      $http_host;
           proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header   X-Forwarded-Proto https;
    

The nginx config is more transparent, for sure. However, for many scenarios
this isn't the full list of additional headers on your reverse proxy. Every
admin will stumble sooner or later on strange wrongly generated "internal"
links by some applications, and will learn the hard way to add more headers,
and will never be sure if they really chaught everything. Sure there is
community support, but this still means every admin has to do the same kind of
research.

It may be good for your ego, some "secret" knowledge that distiguishes you
from beginners. But as soon as you get over it, you realize this is just a
waste of time.

If this is the task of the software, however, the whole developer community
can collect the list of headers and their exact values. Everyone who updates
their webserver will benefit immediately. Everyone who installs their
webserver for the first time don't even have to bother with that exact header
list.

~~~
mdekkers
As an ops guy that needs to look after many different configs for many
different clients all using many different stacks, your comment surprises me.

Configuration being solved within the software itself? Either I am going to
end up with "magic" that may or may not work, and may or may not behave
predictably in a given scenario (predictable behaviour is somewhat important
for ops), or I am going to end up with every single config scenario enshrined
within the software itself, something that I thought was established as a
software anti-pattern around the time of Ada Lovelace.

As the OP stated, the "transparent" option is meaningless without a manual.
The nginx (or whatever verbose software config option set) syntax is
meaningful, and more importantly, predictable. By spelling out those lines I
know exactly what I can expect the software to do in some given scenario.

The whole "I don't want to worry about/understand configuration" meme is
dangerous. You end up with no real understanding of how your stack functions.
You are trading off deep understanding of your stack - a benefit for the
lifetime of your product - with reducing 30 minutes configuring stuff to 5,
which buys you 25 minutes not having to grok the engine of your app.

I personally don't care about having to spend time to configure. I don't care
if it is written in Golang, Python, C++, or Sanskrit. I care about
performance, security, footprint, and configurability. Remove any of those,
and your fancy new toy service just went from "might be interesting for
production" to "useless".

Ops and magic don't mix very well.

I'm surprised this actually needs to be explained. As for it being good for an
ego, that kind of statement is ridiculous.

------
izietto
What's wrong with this?

    
    
      server {  
          listen 80;
          server_name blog.kixpanganiban.com;
          return 301 https://$server_name$request_uri;
      }
    
      server {  
          listen      443 ssl;
          server_name blog.kixpanganiban.com;
          ssl_certificate /etc/letsencrypt/live/blog.kixpanganiban.com/fullchain.pem;
          ssl_certificate_key /etc/letsencrypt/live/blog.kixpanganiban.com/privkey.pem;
    
          charset     utf-8;
    
          # max upload size
          client_max_body_size 75M;
    
          location / {
             proxy_set_header   X-Real-IP $remote_addr;
             proxy_set_header   Host      $http_host;
             proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
             proxy_set_header        X-Forwarded-Proto https;
             proxy_pass   http://localhost:2368/;
          }
      }
    

Every line is self-explanatory, blocks define clearly where some directive is
applied and where not, you just have to read some well-written docs in order
to spot the right directive. And this came after Apache configuration mess,
when almost nothing did better. Maybe lighttpd, but lighttpd was missing of
some essential web server options.

~~~
icebraining
I think the point is that the default configuration is too verbose; after all,
you don't have to touch most Nginx options for a typical configuration, so why
do you still have to configure so much stuff?

I think the point has some merit, though I personally don't really care.

------
oskarth
_It would be no exaggeration to say that Caddy, an up-and-coming HTTP /2
server written in Go that's been gaining a lot of traction, is outright
witchcraft. Out of the box, it just works. With HTTPS. With very little
configuration._

And the server is down. Irony.

~~~
safeharbourio
he spoke way too quick

~~~
SFJulie
not QUIC but HTTP2.0

------
kixpanganiban
Bleh, this is embarassing. Node in my bottom-tier Lightsail instance is unable
to handle the traffic (big surprise) and now I'm starting a bigger instance
from a snapshot.

In response to some of the comments:

1\. I absolutely agree that knowing exactly what something does line by line
is much better than "magic". But that's the thing, if you know Caddy as much
as you know Nginx, you'd be able to explain every single one of those 4 lines:

> blog.kixpanganiban.com

Because I didn't bind it specifically to a port (didn't add :80 or :443), I
know that Caddy will automatically serve it over HTTPS for me and bind it to
both. I could have written `blog.kixpanganiban.com:80` instead if I wanted it
to be HTTP-only, or even
`[http://blog.kixpanganiban.com/blog/`](http://blog.kixpanganiban.com/blog/`)
if I wanted to serve it on the `/blog` path.

> proxy / localhost:2386 {

Pretty self-explanatory, it proxies all requests to `/` to the
`localhost:2386` (Ghost) backend. I could attach a list of backends to make it
act as a load-balanced reverse proxy similar to nginx, like so: `proxy /
localhost:2375 somesite.com:2312 {`.

> transparent

Caddy configs call this a "preset", basically a shorthand for:

header_upstream Host {host}

header_upstream X-Real-IP {remote}

header_upstream X-Forwarded-For {remote}

header_upstream X-Forwarded-Proto {scheme}

2\. I'm not trying to sell snake-oil, I'm trying to introduce a perfectly good
alternative which I've been meaning to try for a while. Also, Caddy docs:
[https://caddyserver.com/docs/](https://caddyserver.com/docs/)

~~~
tyingq
Caddy has plenty of fans here, I like it as well. I think you just got bit by
the irony of making the comparison with nginx. Particularly because with
nginx, you could have added some caching with a few configuration directives.

With two relatively new options (caddy and ghost), and the traffic spike,
you're stuck with the downside of new...no established built-in option to
cache.

~~~
kixpanganiban
Yeah, I realize how shortsighted I was. Perhaps adding a caching middleware
along with what I learned fom you guys would be a good exercise (and follow up
post).

------
ComputerGuru
Site is (currently) down, for what it's worth. Someone blogging too early
about their"success?"

~~~
tyingq
Next up..."How to configure a caching reverse proxy for Caddy"

~~~
pi-rat
... using nginx

------
onion2k
Looking at the caddy configuration it's unclear what it's actually doing. From
the article " _After step 5, Caddy prompted me to enter my email for the
LetsEncrypt cert. In the background, it took care of signing me up for LE,
verifying my domain ownership, and downloading and attaching my cert files._ "
That means I can't ssh on to a server, cat the http server config file(s), and
know what's actually happening. That alone is enough for me to not use it.

~~~
icebraining
How so? It just has different defaults; as long as you know which those are,
you know what's happening, just like with Nginx.

~~~
onion2k
nginx doesn't have defaults for most things. If you don't specify a feature
then it's not used. Consequently reading a config file makes it very obvious
what's happening - to debug a server that's acting up you can look at the
config and if you don't see a value then you need to specify one, and if you
do then something is clearly broken. In a Caddyfile it appears that wouldn't
be the case because it could be using SSL even if the config values are
missing.

~~~
kixpanganiban
No, SSL is not gonna be served if you didn't specify it in the Caddyfile. I
implicitly did, by leaving out the binding port in my server name. I could
have done `blog.kixpanganiban.com:80` and configured Caddy NOT to handle
HTTPS. I think a lot of people incorrectly think that because something was
not written, it was not configured, which isn't the case.

------
shocks
Link is down...

Cache:
[https://webcache.googleusercontent.com/search?q=cache:MK6zOl...](https://webcache.googleusercontent.com/search?q=cache:MK6zOl_SgQoJ:https://blog.kixpanganiban.com/switching-
from-nginx-to-caddy/+&cd=1&hl=en&ct=clnk&gl=uk)

------
sametmax
Oh, the irony. They website is now down, with an nginx error message.

------
soulchild37
502 Bad Gateway From Nginx.... I am perplexed...

~~~
kixpanganiban
Chill out, I respawned the server and forgot the nginx is still on upstart,
which is why it took over before I could start caddy :)

------
macygray
I've opened a link and got 502 Bad Gateway from ginx/1.10.0 (Ubuntu)

=) nice

~~~
rycfan
He's working on his "Switching from Caddy to nginx article" right now.

------
celsoazevedo
"502 Bad Gateway

nginx/1.10.0 (Ubuntu)"

~~~
coldcode
Maybe they should use Caddy?

