[HN Gopher] Caddy - The Ultimate Server with Automatic HTTPS
       ___________________________________________________________________
        
       Caddy - The Ultimate Server with Automatic HTTPS
        
       Author : huang_chung
       Score  : 380 points
       Date   : 2025-02-16 17:56 UTC (5 hours ago)
        
 (HTM) web link (caddyserver.com)
 (TXT) w3m dump (caddyserver.com)
        
       | bradley_taunt wrote:
       | Streamlined "tutorial" for those looking to easily get up and
       | running with Caddy:
       | 
       | https://caddy.ninja/
        
       | therein wrote:
       | I'd imagine most of everyone here knows about Caddy. Even mholt.
       | :)
        
       | upghost wrote:
       | Interesting. Is this supposed to be an NGINX/reverse-proxy
       | replacement, or is it complementary?
        
         | geocrasher wrote:
         | My understanding is that it is standalone.
        
         | vunderba wrote:
         | It's a standalone replacement for NGINX / Apache. I swapped
         | over to it years ago and it's been rock solid, handles HTTPS
         | certificates via ZeroSSL, and config files are very simple to
         | set up. The author of the project is also really responsive.
        
       | arccy wrote:
       | despite knowing what caddy is, this site turns me off for all the
       | marketing fluff.
       | 
       | since when was hn for ads? there's nothing notably technical on
       | the page
        
         | BoingBoomTschak wrote:
         | I agree that the website isn't very appealing for techies.
         | Still what I use to serve my website, so simple a chimp could
         | deploy with it; though I'm kinda dreading the moment I'll put
         | cgit behind it.
        
         | lolinder wrote:
         | > By default, Caddy automatically obtains and renews TLS
         | certificates for all your sites.
         | 
         | This is pretty technical, and is an absolute game changer for
         | local TLS setups. Three paragraphs under this quote go into
         | more details.
         | 
         | Then a third of the way down the page there's a way to try it
         | out live by changing your DNS records. Right after that are a
         | few config samples. Then there are links to three different
         | white papers. Then more code samples. Then more more code
         | samples.
         | 
         | You get the idea.
         | 
         | What exactly are you missing here as far as technical stuff? Is
         | it just that they add exciting fonts and stuff on top of the
         | technical stuff?
        
           | arccy wrote:
           | it's all just marketing fluff
        
             | kupopuffs wrote:
             | r u sure you want the technical stuff?
        
               | arccy wrote:
               | it looks like any other marketing site, no talk of how or
               | why anything in particular is implemented the way it is,
               | doesn't admit to any tradeoffs or limitations, all
               | positive spin designed to lure you in.
        
             | lynndotpy wrote:
             | Not sure how this is "fluff". That's a feature that has
             | significant appeal for me as a sysadmin. The landing page
             | is full of demos and technical features relevant for anyone
             | who needs an HTTP server.
             | 
             | It took me ten minutes with Caddy to replace five years of
             | Apache+Nginx. That was three years ago.
        
       | geocrasher wrote:
       | Last year a coworker mentioned Caddy, so I decided to set it up
       | on a spare box just to see how well it worked with WordPress, PHP
       | etc. It did okay. I didn't do any big tests with it but it seemed
       | to work well enough, and was super simple to configure. It does
       | seem quite niche however.
        
         | jasongill wrote:
         | I have had "move our PHP infrastructure to FrankenPHP" on my
         | todo list for the last year or two - it's Caddy combined with
         | PHP in Go
        
           | napkid wrote:
           | I did exactly this for my startup (https://easy.green). I'm
           | very happy with this setup so far, with the code embedding
           | feature for on premise delivery. I had to disable the worker
           | mode though, it caused issues with uncommon features in the
           | ORM.
        
         | DerSaidin wrote:
         | > It did okay. I didn't do any big tests with it but it seemed
         | to work well enough, and was super simple to configure.
         | 
         | What issue/experience stop you from saying "it did great"?
        
       | samwillis wrote:
       | One area we have found Caddy invaluable is for local testing of
       | APIs with HTTP2 during development. Most dev servers are HTTP1
       | only, and so you are limited to max of 6 concurrent connections
       | to localhost. HTTP2 requires SSL, which would normally make it a
       | PITA to test/setup locally for development.
       | 
       | Throw a Caddy reverse proxy in front of your normal dev server
       | and you immediately get HTTP2 via the root certificate it
       | installs in your OS trust store.
       | (https://caddyserver.com/docs/automatic-https)
       | 
       | We (ElectricSQL) recommend it for our users as our APIs do long
       | polling, which with HTTP2 doesn't lock up those 6 concurrent
       | connections.
       | 
       | I've also found that placing it in front of Vite for normal
       | development makes reloads much faster. Vite uses the JS module
       | system for loading individual files in the browser with support
       | for HMR (hot module replacement), this can result in a lot of
       | concurrent requests for larger apps, creating a queue for those
       | files on the six connections. Other bundlers/build tools bundle
       | the code during development, reducing the number of files loaded
       | into the browser, this created a bit of a debate last year on
       | which is the better approach. With HTTP2 via Caddy in front of
       | Vite you solve all those problems!
        
         | jsheard wrote:
         | > HTTP2 requires SSL
         | 
         | Strictly speaking it doesn't, unencrypted HTTP2 is allowed per
         | the spec (and Caddy supports that mode) but the browsers chose
         | _not_ to support it so it 's only really useful when testing
         | non-browser clients or routing requests between servers. HTTP3
         | does require encryption for reals though, there's no opting out
         | anymore.
        
           | samwillis wrote:
           | Yep, it's really disappointing they didn't decide to support
           | it for localhost.
        
             | imdadadani wrote:
             | I think the reason why they have decided to not support it
             | over plain text is because they would have to detect if the
             | server answers with HTTP/2 or HTTP/1.1, which could be
             | complicated. This is not needed when using TLS since ALPN
             | is used instead
        
               | jrockway wrote:
               | This is meh excuse. If you want your browser to connect
               | to a gopher server, you type gopher://example.com. If you
               | want to use http2, http2://example.com should work. (I
               | know, I know, everyone removed Gopher support a few years
               | ago. Same idea though.)
               | 
               | Having said all that, I just copied the certs out of here
               | https://cs.opensource.google/go/go/+/refs/tags/go1.24.0:s
               | rc/... and use them to do browser/http2 stuff locally.
               | Why steal Go's certificates? Because it took 1 second
               | less than making my own!
        
               | taftster wrote:
               | Hey, thanks for this. It saves me even more than 1
               | second!
        
               | e12e wrote:
               | Which browsers/libraries trust these? Or does the go tool
               | chain install them?
        
               | johannes1234321 wrote:
               | Using http2 as protocol in the URL makes the initial
               | transition complex: One can't share links between
               | different users and clients and from other websites with
               | a guarantee of the "best" experience for the user. Not to
               | mention all old links outside the control of the server
               | operator.
        
               | zinekeller wrote:
               | No, that's rather easy for up-to-date browsers. The real
               | reason is that dumb middle proxies might cache/mangle
               | HTTP/2 requests to the point that it simply fails hard,
               | but encryption makes those concerns go away. Yes, there
               | are proxies that can decrypt TLS, but due to how
               | negotiation of HTTP/2 works in TLS (ALPN), dumb proxies
               | will simply not send the signals that it's HTTP/2
               | capable.
        
         | tacone wrote:
         | Another way is to create a regular DNS name, and ave it
         | redirect to localhost. If you are unable or unwilling to do so,
         | there are free DNS services like https://traefik.me/ that
         | provide you with a real domain name and related certificates.
         | 
         | I personally use traefik.me for my hobbyist fiddling, and I
         | have a working HTTP/2 local development experience. It's also
         | very nice to be able to build for production and test the
         | performance locally, without having to deploy to a dev
         | environment.
        
           | 8n4vidtmkvmk wrote:
           | Aren't you exposing your dev instance to the world then? Not
           | worried about that?
        
             | adolph wrote:
             | DNS to a local address doesn't expose anything.
             | 
             | For example, postulate a DNS entry of myTopSecrets mapped
             | to localhost. If you use it, it will be routed to your own
             | computer. If someone else uses it, they would be routed to
             | their own computer. The same follows for IP addresses
             | within your local area network.
             | 
             | Unless you did extra work outside the scope of DNS, nothing
             | in your lan is addressable from outside your lan.
        
               | TeMPOraL wrote:
               | You're still revealing the existence of myTopSecrets to
               | the world, though.
               | 
               | Between this and certificate transparency logs, it seems
               | _insane_ to me that the commonly advised Correct Setup,
               | to be able to experiment and hack random little personal
               | stuff, and have it reliably work on modern browsers,
               | requires you to 1) buy a subscription (domain), 2) enter
               | into another subscription-ish contractual relationship
               | (Let 's Encrypt), and 3) announce to the whole world what
               | you're doing (possibly in two places!).
               | 
               | Imagine your computer stops booting up because you
               | repositioned your desk, and everyone tells you the
               | Correct Way to do it is to file a form with the post
               | office, and apply for a free building permit from the
               | local council. That's how this feels.
        
               | Reubensson wrote:
               | Couldn't you just add the domain to /etc/hosts and have
               | it resolve that way. No need to buy domain if you are
               | just testing locally. Also you wouldn't be exposing
               | anything to outside world.
        
               | TeMPOraL wrote:
               | Perhaps I could, but I'm afraid to do it[0]. And I'd
               | still need a matching certificate, and generating a one
               | that browsers won't refuse to look at _and_ make them
               | trust it across multiple devices (including mobile) is it
               | 's own kind of hell.
               | 
               | --
               | 
               | [0] - I'm honestly afraid of DNS. I keep losing too much
               | of my life to random name resolution failures, whose
               | fixes work non-deterministically. Or at least I was until
               | ~yesterday, when I randomly found out about
               | https://messwithdns.net, and there I learned that
               | nameservers are required to have a _negative cache_ ,
               | which they use to cache _failed lookups_ , often with
               | absurdly high timeout values. That little bit of
               | knowledge finally lets me make sense of those problems.
        
               | Reubensson wrote:
               | I was only commenting about DNS part, self signed
               | certificates come with their own lot of trouble. At least
               | I havent ever run into any cache issues with local
               | resolvers.
               | 
               | I have previously used https://github.com/jsha/minica
               | which makes it at least easy to create a root certificate
               | and matching server cert. How to get that root cert
               | trusted on different array of devices is another story.
        
               | IncRnd wrote:
               | myTopSecrets can instead be mapped through a local
               | redirection without needing to put that information out
               | onto the Internet.
        
           | imhoguy wrote:
           | It is even simpler with `/etc/hosts`:
           | 127.0.0.1 localhost local.foobar.com
           | 
           | And just use wildcard `*.foobar.com` or SAN cert with
           | anything local like Caddy, Nginx, Haproxy or whatever.
        
         | peterldowns wrote:
         | Completely agree. If you want a nice way to do this with a
         | shared config that you can commit to a git repo, check out my
         | project, Localias. It also lets you visit dev servers from
         | other devices on the same wifi network -- great for mobile
         | testing!
         | 
         | Localias is built on Caddy; my whole goal is to make local web
         | dev with https as simple as possible.
         | 
         | https://github.com/peterldowns/localias
        
         | JasonSage wrote:
         | Just a note, because this comment made me curious and prompted
         | me to look into it:
         | 
         | Vite does use HTTP2 automatically if you configure the cert,
         | which is easy to do locally without Caddy. In that case
         | specifically there's no real reason to use Caddy locally that I
         | can see, other than wanting to use Caddy's local cert instead
         | of mkcert or the Vite plugin that automatically provides a
         | local cert.
        
         | srameshc wrote:
         | I assumed almost everyone (product, enterprise) uses ngork to
         | expose development/localhost server to get HTTP2 now a days,
         | but it's good to realize Caddy can do the job well.
        
       | hollow-moe wrote:
       | Caddy is already powerful as it is but with the L4 plugin it can
       | also work on layer 4 and proxy other stuff. I made a cursed
       | config proxying to a website on HTTP request and towards a
       | Minecraft server all other TCP traffic.
        
         | gear54rus wrote:
         | is there write up or code for that?
        
           | therein wrote:
           | Here using `layer4.matchers.*`
           | 
           | https://github.com/mholt/caddy-l4?tab=readme-ov-
           | file#introdu...
        
       | kstrauser wrote:
       | I migrated all my Nginx hosts to use Caddy a while back. It
       | doesn't do anything Nginx can't, but the default configuration is
       | identical to the way I'd previously manually configured servers.
       | It's so pleasant to get an HTTPS site up and running with 3 lines
       | of setup.
        
       | sagolikasoppor wrote:
       | I have used caddy for years as a reverse proxy for all my side
       | projects. It is one of my favorite pieces of software.
       | 
       | So easy to setup and performs very well.
        
       | satvikpendem wrote:
       | Caddy is pretty nice, I believe Coolify uses it as part of their
       | self-hosted open source PaaS model. Just out of curiosity, are
       | there any alternatives in Rust? I think Pingora is one, as well
       | as River which is built on top of it [0], but I'm not sure how
       | widely used the latter is as a Caddy replacement.
       | 
       | [0] https://github.com/memorysafety/river
        
         | aquariusDue wrote:
         | As far as I know only NGINX Unit[0] might be considered a
         | viable-ish real alternative to Caddy. But other than that
         | nothing comes close to Caddy's ease of use and versatility. You
         | get a lot of stuff and there are heaps of community modules for
         | it, the only downside last time I checked was increased memory
         | usage compared to standard nginx and slower performance as a
         | reverse proxy.
         | 
         | Depending on your setup the fact that you have to choose
         | between Caddyfiles (which are easier to reason about than nginx
         | config files) or the REST API for configuration might be a
         | downside to some people. There's a chance I might be wrong
         | about this one though.
         | 
         | But to answer your question directly there are no real
         | alternatives in Rust as of now.
         | 
         | [0] https://unit.nginx.org/
        
         | cycomanic wrote:
         | AFAIK traefik is written in rust. I don't have any experiences
         | with it though. I only had a brief look when setting up some
         | personal project, but ended up going with caddy, because
         | traefik seemed overkill for my requirements.
        
           | satvikpendem wrote:
           | Traefik is also written in Go, actually.
        
       | rand846633 wrote:
       | Reading the website top to bottom, I'm now unsure about the
       | trustworthiness of a project that seems so full of itself.
       | Passage after passage about how great it is leaves a bad
       | aftertaste. Maybe it's just me--unsure.
       | 
       | I no longer trust the authors to be honest about known
       | shortcomings, let alone be upfront, truthful, and transparent
       | when dealing with security issues and reported vulnerabilities.
       | 
       | I hope I'm wrong. Does anyone know how they've handled
       | disclosures in the past?
        
         | CharlesW wrote:
         | Caddy is nearly a decade old, and is very well-regarded.
         | 
         | https://hn.algolia.com/?dateRange=pastYear&page=0&prefix=fal...
         | 
         | https://en.wikipedia.org/wiki/Caddy_(web_server)
        
         | jeroenhd wrote:
         | I dislike this style of documentation as well, but Caddy is a
         | proven piece of technology. It can easily replace nginx or any
         | other reverse proxy unless you're using a real niche
         | configuration. Not needing to deal with certbot is also pretty
         | nice.
         | 
         | Caddy's writing style isn't necessary big-enterprise-middle-
         | management-friendly, but luckily for big enterprises that want
         | lengthy, dry, and boring, there are plenty of alternatives.
        
         | Deukhoofd wrote:
         | You're unsure about a product because the landing page is
         | positive, and even go so far as to not trust the authors any
         | more? That does sound like a strange expectation for a landing
         | page, which is usually intended to make you want to use a
         | project.
        
           | layer8 wrote:
           | I agree with the GP that hyperbole on a landing page (or
           | anywhere else in the project's communication) makes me not
           | want to use the project. It communicates that the project
           | lacks confidence that a down-to-earth description would speak
           | for itself.
        
           | t43562 wrote:
           | I understand the attitude because there are a lot of
           | corporate websites which similarly claim the moon and the
           | stars and when you dig right down a lot of it is bullshit. I
           | have worked in places like this.
           | 
           | Such companies tend to imply that their product can do
           | anything and tend to have pages of verbiage rather than the
           | brass tacks README with examples you get on a good open
           | source project's github page.
        
         | troyvit wrote:
         | I just had my first experience with Caddy setting it up as a
         | reverse proxy in front of Vaultwarden. Following along with
         | Vaultwarden's documentation it worked like a charm and I was
         | left thinking, "What a neat little project for hobbyists who
         | want to get going quickly with the basics."
         | 
         | Then I checked out the home page and it's all "The most
         | advanced HTTPS server in the world Raaawwrrr!"
         | 
         | Quite the divergence, but as other comments in the thread say,
         | it's a legit good project.
        
       | vFunct wrote:
       | Another great web server to try is h2o: https://h2o.examp1e.net/
       | 
       | Especially for its HTTP/2 and HTTP/3 QUIC support.
        
         | shawnz wrote:
         | Wow, this is exactly what I've been looking for: lightweight,
         | supports CONNECT and CONNECT-UDP with all three HTTP versions,
         | and supports encrypted client hello. Thanks for the
         | recommendation!
        
         | assimpleaspossi wrote:
         | Agree and have been using it for many years for web sites we
         | develop for customers. H3 support has been available for quite
         | some time.
         | 
         | Support is also good and the developer is quite active.
        
         | pbowyer wrote:
         | h2o is also one of the few servers to get resource
         | prioritization correct for HTTP/2 and HTTP/3.
         | 
         | If resource prioritisation is new, a few references:
         | https://www.youtube.com/watch?v=MV034VqHv5Q
         | https://calendar.perfplanet.com/2022/http-3-prioritization-d...
         | https://github.com/andydavies/http2-prioritization-issues
        
       | hagbard_c wrote:
       | I prefer to keep certificate management separate from individual
       | applications like web servers, mail servers, XMPP servers,
       | database servers and all the other services I run. All of these
       | need certificates so I have centralised certificate management
       | and distribution. This comes down to running _certbot_ in a
       | container with some hook scripts to distribute new or updated
       | certificates to services (running on different containers and
       | machines) which need them, restarting those services when needed.
       | Adding a new site to _nginx_ comes down to copying a template
       | configuration, changing the site name to the correct one, adding
       | whatever configuration needed for the specific service and
       | requesting a new certificate for it. The new certificate
       | automatically gets copied to the container or machine running the
       | service so it is available after reloading the _nginx_
       | configuration. The same is true for most other services, several
       | of which share certificates because they 're running in the same
       | domain. I used the same scheme back when I used _lighttpd_ and
       | will probably use it should I move to another web (or mail or
       | XMPP or whatnot) server.
        
         | defanor wrote:
         | Same here (not certbot and containers, but the part about
         | reusing certificates for multiple services): it feels wrong to
         | couple certificate acquisition with a web server. Apparently it
         | is convenient when there is just a web server out of TLS-using
         | services, or at least when it is in the center of the setup and
         | HTTP-based certificate acquisition is used, which seems to be a
         | common enough case to justify this, but still an odd coupling
         | in general.
        
         | RadiozRadioz wrote:
         | I also do this same thing, but my Nginx configs are templated
         | out via automation. It gives me the best of both worlds: 95% of
         | my sites and their certs are templated out from 3 lines of
         | config each, then for the last special 5% I can insert literal
         | Nginx config. For most uses I have the same experience as
         | someone with Caddy, but for that last 5% I love the "access the
         | full power of Nginx config from the same place" escape hatch.
        
       | wim wrote:
       | I also find their library for Go
       | (https://github.com/caddyserver/certmagic) a major timesaver!
       | We're using it to make it easy for people to self-host our app
       | and it takes care of all the TLS cert set up/renewal.
        
       | pierot wrote:
       | A great alternative is Traefik. We have been using v1 and v2 for
       | several years now in a setup that uses the docker labels for
       | configuration of services.
        
         | therein wrote:
         | When I had first heard of Caddy, I was experimenting with
         | Traefik to replace an nginx setup I had for a long time.
         | 
         | Traefik had good potential and momentum at the time. And then
         | Caddy started to gain some momentum too. After that there was a
         | brief moment Caddy made the mistake of taking an ad and
         | including it in the `Server` response header and making it be
         | an opt-out feature. Once that was walked back and the dust has
         | settled, Caddy kept gaining more and more momentum and
         | exposure.
         | 
         | Traefik had a web panel that I thought was cool back then but
         | it tried to be too tightly coupled with containers and insisted
         | on making service discovery be an essential core component of
         | its configuration model.
         | 
         | At least this is what I remember. At this point I am very happy
         | with caddy and it is what I use pretty much on all my services.
         | 
         | Thank you mholt for such a nice project and sorry for being
         | overly critical of the ad in the Server response header very
         | many years ago. :)
        
           | paulgb wrote:
           | In case anyone is (like me) unfamiliar with the server header
           | ad: https://news.ycombinator.com/item?id=15237923
           | 
           | Glad they removed it. Caddy is a great piece of software.
        
         | qntmfred wrote:
         | I also started using traefik a while back with docker labels.
         | it was a bit more to set up than I thought it would be, but now
         | that I've figured it all out it's not too bad.
         | 
         | at the time I had seem a lot of people talking about caddy as
         | well and considered using it instead, but traefik had better
         | perf/latency benchmarks and caddy seemed a bit too much geared
         | toward or at least better suited for dev environment scenarios.
        
       | gz5 wrote:
       | The friendly licensing (Apache v2) is important too, especially
       | w/ Caddy's modular architecture (single, static binary compiled
       | for any platform).
       | 
       | Meaning ecosystems around Caddy to make it even simpler and more
       | secure, e.g. keep your server private while serving Internet
       | clients. So VPNs like Tailscale (1) or zero implicit trust like
       | OpenZiti (also Apache v2; (2)). Similar to what we have seen with
       | open source k8s ecosystem for example.
       | 
       | (1) https://tailscale.com/blog/caddy (and other VPNs but the
       | proprietary bits in the commercial TS service make it easier to
       | use)
       | 
       | (2) https://github.com/openziti-test-kitchen/ziti-caddy
       | (disclosure: maintainer...there may be other open source zero
       | implicit trust options with these types of Caddy integrations)
        
         | trashburger wrote:
         | > modular architecture
         | 
         | > single, static binary compiled for any platform
         | 
         | Huh? Aren't these exact opposites?
        
           | mholt wrote:
           | Plugins (modules) are compiled in statically.
        
             | pjmlp wrote:
             | Just like in the 1980's.
        
       | martinbaun wrote:
       | I absolutely love Caddy. Used it for years. Very reliable and so
       | easy to setup once you learn the basics. The documentation is a
       | bit hard to get, but it saved me so much time and energy compared
       | to trying to get letsencrypt working reliable ontop of NGINX.
        
         | codetrotter wrote:
         | I used Caddy for a couple of years but eventually went back to
         | Nginx.
         | 
         | For the Let's Encrypt certs I use certbot and have my Nginx
         | configs set up to point to the appropriate directories for the
         | challenges for each domain.
         | 
         | The only difficulty I sometimes have is the situation where I
         | am setting up a new domain or subdomain, and Nginx refuses to
         | start all together because I don't have the cert yet.
         | 
         | It's probably not too complicated to get the setup right so
         | that Nginx starts listening on port 80 only, instead of
         | refusing to start just because it doesn't have the cert for TLS
         | needed to start up the listener on port 443.
         | 
         | But for me it happens _just_ rarely enough that I instead first
         | make the config and outcomment the TLS /:443 parts and start it
         | so that I can respond to the request from Let's Encrypt for the
         | /.well-known/blah blah stuff, and then I re-enable listening on
         | with TLS and restart Nginx.
         | 
         | I also used DNS verification for a while as well, so I'm
         | already aware that's an option too. But I kind of like the
         | response on :80 method. Even if I've managed to make it a bit
         | inconvenient for myself to do so.
        
         | throwaway94244 wrote:
         | I tried to setup Caddy last year as a reverse proxy for all
         | paths matching "/backend", and serve the rest as static files
         | from a directory. I had to give up, because the documentation
         | was not good enough.
         | 
         | I tried the JSON config format that seems to be the recommended
         | format, but most examples on Google use the old format. To make
         | it even more complicated the official documentation mentions
         | configuration options, without informing that it requires
         | plugins that is not necessarily installed on Ubuntu. Apparently
         | they just assume that you will compile it from scratch with all
         | options included. Lots of time was wasted before I found a
         | casual mention of it in some discussion forum (maybe stack
         | overflow, don't remember). I just wanted the path to be
         | rewritten to remove the "/backend" path before proxying it to
         | the service. I guess that is uncommon for a reverse proxy, and
         | have to be placed in a separate module
         | 
         | I may appear overly critical, but I really spent a lot of time
         | and made an honest attempt
         | 
         | I'll go back to nginx. Setting up let's encrypt requires some
         | additional steps, but at least it's well documented and can be
         | found in Google searches if necessary
        
           | e12e wrote:
           | Sounds like last example here?
           | 
           | https://caddyserver.com/docs/caddyfile/directives/handle_pat.
           | ..
        
           | mholt wrote:
           | Huh, sorry that it was that difficult. Based on what you
           | wrote, this should suffice:                   example.com
           | root /etc/www         reverse_proxy /backend/* 127.0.0.1:8080
           | file_server
        
           | zsoltkacsandi wrote:
           | > I had to give up, because the documentation was not good
           | enough.
           | 
           | I had the same experience. And also somewhat bothered me that
           | even a very basic and common functionality like rate limiting
           | is not built-in.
        
       | rfurmani wrote:
       | I'm serving AI models on Lambda Labs and after some trial and
       | error I found having a single vllm server along with caddy,
       | behind cloudflare dns, to work really well and really easy to set
       | up
       | 
       | vllm serve ${MODEL_REPO} --dtype auto --api-key $HF_TOKEN
       | --guided-decoding-backend outlines --disable-fastapi-docs &
       | 
       | sudo caddy reverse-proxy --from ${SUBDOMAIN}.sugaku.net --to
       | localhost:8000 &
        
         | delduca wrote:
         | You can use Cloudflare Tunnel, which is even better and simple
         | than having an extra service.
        
       | andrewstuart wrote:
       | One day a number of years ago I decided I'd totally had anough of
       | the arcane and difficult to debug Nginx configuration.
       | 
       | I heard about how Caddy did automatic https, and given the
       | searing pain of doing https on Nginx, decided to make the switch.
       | 
       | Never regeretted it. Caddy it always up to the job even for
       | sophisticated reverse proxying configs.
        
       | NetOpWibby wrote:
       | I just launched a new site with Caddy today: https://uchu.style
       | 
       | Caddy is so awesome. I actually have a few other sites on the
       | same server and updating my config is hella simple.
       | 
       | I spent several years optimizing my nginx setup and I haven't
       | touched it in years (I was obsessed about getting a perfect
       | security score).
        
       | oliwary wrote:
       | Caddy coupled with Caddy-Docker-Proxy [0] is a marvelous way to
       | set up a server with multiple docker projects. I have it running
       | on a couple of servers, and it just works!
       | 
       | [0] https://github.com/lucaslorentz/caddy-docker-proxy
        
         | globular-toast wrote:
         | I used this for my homelab before I decided my life was too
         | easy and switched to k8s+cert manager. I use traefik[0] to
         | handle multiple docker-compose projects in development, but
         | this is pretty much a drop in replacement and gets you HTTPS if
         | you have a domain and your registrar has an API. I ran a single
         | docker-compose file with everything in it behind a single
         | reverse proxy for quite a while.
         | 
         | [0] https://blog.gpkb.org/posts/multiple-web-projects-traefik/
        
           | plagiarist wrote:
           | This will be interesting to read, thank you. This sounds like
           | what I was struggling with a while ago.
           | 
           | I found traefik to be a small nightmare in k8s. I struggled
           | my way up to a working implementation years ago, then a k8s
           | version change on my k8s hosting service forced me to start
           | from scratch.
           | 
           | The whole thing soured me on traefik and also k8s. I wanted
           | to learn pods and autoscaling while having interservice
           | networking resolved for me. I don't want to spend hours
           | struggling with the ingress and load balancing tools (I
           | thought) k8s is supposed to solve for me.
           | 
           | If I ever try it again, I'd use a different ingress tool for
           | sure.
        
             | globular-toast wrote:
             | I used traefik ingress for a while for k8s as it is
             | included by default with k3s. But I very quickly switched
             | to ingress-nginx. It's very easy to install and then it
             | just takes care of itself letting you just declare
             | Ingresses and forget about it.
        
         | twasold wrote:
         | Have you tried Traefik? Could you compare the two? I was going
         | to migrate to traefik soon but would consider any alternative
        
       | ulrischa wrote:
       | I get sick when I think about migrating my htaccess and apache
       | rules to this format
        
       | 101008 wrote:
       | I couldn't find (using Google _) a good tutorial to deploy Django
       | with Caddy to a Digital Ocean droplet. Can anyone suggest me what
       | I should look for?
       | 
       | _ I could ask a LLM but I 'd prefer the old way for this type of
       | stuff...
        
       | rmm wrote:
       | I love love caddy. I only use it for my homelab to get https
       | everywhere, but it's so much easier than traefik for me I
       | honestly don't know why everyone prefers it? What am I missing?
        
         | lurking_swe wrote:
         | Traefik just integrates better with docker, especially docker
         | compose. Depends on your use case honestly.
         | 
         | nothing wrong with caddy.
        
       | sunaookami wrote:
       | Love Caddy! Switched to it 2 years ago from NGINX/OpenResty and
       | it made my config much less verbose and more simple. Previously
       | used lua-resty-auto-ssl with OpenResty but it's kinda deprecated
       | and I will never touch certbot but needed a "fire-and-forget"
       | solution. Serving 70k visitors monthly very well :)
        
       | 8n4vidtmkvmk wrote:
       | A lot of positivity in this thread. I don't have anything bad to
       | say about Caddy, but the only advantage I'm hearing over Nginx is
       | easier cert setup. If you're struggling with that, I can see how
       | that's a benefit.
       | 
       | I configured my kubernetes cluster to automatically create and
       | renew certs a few years ago. It's all done through Ingress now. I
       | just point my Nginx load balancer to my new domain and it figures
       | it out.
       | 
       | I don't often need local https but when I do I also need outside
       | access so Stripe or whatever can ping my dev server (testing
       | webhooks). For that I have a server running Nginx which I use to
       | proxy back to localhost, I just have to run 1 command to
       | temporarily expose my machine under a fixed domain.
       | 
       | Works for me. Maybe not everyone but I'll keep doing this since I
       | don't have any reason to switch
        
         | thomasfromcdnjs wrote:
         | - Single executable (you know where all the files are
         | regardless of os)
         | 
         | - Config so easy you can remember how to do it in a day
        
           | lynndotpy wrote:
           | This is it for me. I got frustrated trying to do something
           | with Nginx, which I had ~five years of experience with at the
           | time.
           | 
           | Someone recommended I try Caddy, I was surprised I could just
           | `chmod +x caddy; caddy start`, and I had replaced my
           | laborious Nginx configuration + the new reverse proxy I
           | wanted in ten minutes.
           | 
           | If I already knew Nginx in-and-out, I'd not have had the
           | impetus to use Caddy. If Nginx config is a daunting task or
           | something that takes longer than two minutes, I'd recommend
           | taking a few minutes to try out Caddy.
        
           | homebrewer wrote:
           | > Single executable (you know where all the files are
           | regardless of os)
           | 
           | This is your package manager's job, which even Windows has
           | these days. Other operating systems solved this problem
           | decades ago.
           | 
           | https://winstall.app/apps/nginxinc.nginx
        
             | TeMPOraL wrote:
             | They're not solving it well in many cases; so-called
             | "portable apps" are a great thing.
             | 
             | (If you don't believe me, consider why exactly Docker got
             | so popular.)
             | 
             | In a way, it's ironic that you need package managers to
             | keep track of software on Linux, compared to Windows, which
             | used to let you get away with the assumption that
             | everything that makes a program lives in a single folder
             | tree; half the software was effectively portable by
             | default.
             | 
             | Where's the irony, you ask? On Windows, you could almost
             | say that an application install is equivalent to its
             | folder. And a folder is a type of file. And per Unix
             | philosophy, everything is supposed to be a file!
        
               | pjmlp wrote:
               | Everything is a file is only true if we ignore OS IPC and
               | networking.
               | 
               | Windows way goes back to 8 and 16 bit home computer days,
               | across all systems that is mostly how it worked,
               | applications were placed inside their own directory, or
               | their own floppy, actually.
        
         | Diggsey wrote:
         | I haven't used Caddy but it's config format can't be worse than
         | nginx's. Some crazy gotchas with the way nginx config works...
        
           | homebrewer wrote:
           | > it's config format can't be worse than nginx's.
           | 
           | It's alright -- the main upside for me is that it supports
           | parameterized includes, thus letting you reuse large chunks
           | of configuration without relying on something like ansible or
           | bash + envsubst.
           | 
           | https://caddyserver.com/docs/caddyfile/directives/import
        
           | 8n4vidtmkvmk wrote:
           | That's true. Nginx config has quirks that have bewildered me
           | in the past, but nothing I couldn't figure out, and not
           | something I have to touch often.
        
         | maccard wrote:
         | Caddy is an opinionated alternative to nginx with modern
         | defaults.
         | 
         | I'm perfectly able to configure all of the bits and pieces of
         | nginx or apache, but instead of spending 15 minutes or so doing
         | it I tell caddy "here's my domain name" and move on with my
         | life. The massive benefit is that the features are easily
         | replaced or replicated so if I do decide I want to use traefik
         | or nginx for a specific feature, I can do it when I care about
         | that. But caddy is just batteries included
        
         | homebrewer wrote:
         | > I don't have anything bad to say about Caddy
         | 
         | Here's one: it does not support dynamically loadable modules,
         | like most (all?) Go programs. So if you need e.g. geoip, you
         | have to build your own, and then maintain it, tracking CVEs,
         | etc. You can't rely on your distribution's package maintainer
         | to do the work.
        
           | baby_souffle wrote:
           | This was the big deal-breaker for me when I last looked a
           | little while ago.
           | 
           | I need route 53 and a few other DNS providers built in for
           | let's encrypt support and the docs implied that I was going
           | to have to build those plugins myself?!!!
           | 
           | I stopped reading at that point because cert bot is trivial
           | to install and just works with the web server that was also
           | one command to install. At no point did I have to create a
           | ephemeral container just to build nginx or certbot...
        
           | dboreham wrote:
           | Golang fundamentally doesn't support dynamically loaded
           | libraries. It appears at first that it does, which can waste
           | your time, but actually it doesn't.
        
             | silisili wrote:
             | Can you expand? I thought the plugin package handled this
             | now, though I've not actually tried it. Is it a dud?
        
               | pjmlp wrote:
               | It is one, yes.
               | 
               | Only a POC, supported in Linux and macOS, and basically
               | relies on doing casts from loaded symbols into what they
               | are supposed to mean.
        
           | vruiz wrote:
           | It's not like you have to maintain a fork, it's pretty
           | minimal, all you need is a Dockerfile with what you want and
           | build the container. Other than that you just keep bumping
           | the version like you would the standard distribution.
           | 
           | For example to use rate limiting I just have a Dockerfile
           | like this:
           | 
           | FROM caddy:2.9.1-builder AS builder
           | 
           | RUN xcaddy build --with github.com/mholt/caddy-ratelimit
           | 
           | FROM caddy:2.9.1
           | 
           | COPY --from=builder /usr/bin/caddy /usr/bin/caddy
        
           | apitman wrote:
           | I wonder if caddy3 might implement WASM plugins via something
           | like Wazero. Maybe too much of a performance hit.
        
         | DistractionRect wrote:
         | I think nginx is great if your enterprise and want to squeeze
         | the most utility out of your boxes. The issue is there's a
         | large disconnect between nginx and Nginx plus, and you quickly
         | end up making cursed configs to do basic things if you're using
         | the former. It's literally what drove me to seek out
         | alternatives and settle on caddy years ago.
        
       | engine_y wrote:
       | A couple of years ago, we tried replacing nginx with Traefik. The
       | main reason was its https integration with lets encrypt.
       | 
       | Let's just say it takes a lot these days to choose something that
       | is not nginx.
        
       | inglor_cz wrote:
       | I use Caddy within FrankenPHP and it is a very good server. Plus
       | the community is really helpful.
       | 
       | I wish it had more informative logs, though. Some subtle errors
       | in Caddyfile may result in the server not communicating, and not
       | telling you that something is wrong.
        
       | seaal wrote:
       | After switching from nginx to caddy-docker-proxy a year ago I
       | just recently made the move to Pangolin[0] and am really enjoying
       | the experience. It's a frontend to traefik with built-in auth and
       | ability to tunnel traffic through Wireguard. I needed the TCP
       | forwarding for my Minecraft server and this made it very simple.
       | 
       | Would recommend it for anyone wanting a better version of Nginx
       | Proxy Manager. The documentation is a little lacking so far but
       | the maintainers are very helpful in their Discord.
       | 
       | [0] github.com/fosrl/pangolin
        
         | aborsy wrote:
         | It sounds more like an alternative to Cloudflare Tunnels.
         | Except, the Cloudflare access is secured by Cloudflare security
         | team.
        
           | gloflo wrote:
           | And all your traffic would be watched and monitored by an US
           | American company which already has access to vast amounts of
           | your internet browsing behaviour.
        
             | aborsy wrote:
             | Yes, that's the downside. But if you run Pangolin on a VPS,
             | there is no downside in that respect: in both cases a cloud
             | provider has access.
             | 
             | Authentik behind Caddy does that too.
        
               | apitman wrote:
               | Not sure if Pangolin works this way, but in general it's
               | possible to run tunnels end to end encrypted.
        
             | delduca wrote:
             | OP told that was already using Cloudflare.
        
         | miloschwartz wrote:
         | Glad to see Pangolin mentioned here!
        
       | p2detar wrote:
       | I was reluctant to switch to Caddy because I couldn't understand
       | if does or does not use Linux' sendfile sys call, which made a
       | huge difference for me with Nginx. [0]
       | 
       | Nevertheless, I used Caddy to front our internal Mattermost chat
       | server and it works flawlessly to date. The configuration was
       | really simple, I like it a lot.
       | 
       | 0 - https://github.com/caddyserver/caddy/issues/4731
        
         | commandersaki wrote:
         | My hunch is that sendfile isn't going to give any discernable
         | improvement and looking at the benchmarks in the thread that
         | seems to confirm this.
        
           | jsheard wrote:
           | IIRC Caddy uses sendfile on HTTP connections, but HTTPS
           | connections are or were blocked by Go not supporting Kernel
           | TLS yet. If the kernel is sending the file by itself then it
           | also has to handle the crypto.
        
       | Levitating wrote:
       | I am still looking for a dead simple webserver that can serve
       | files, do CGI and reverse proxy.
       | 
       | I have been using lighttpd for much of this. It's configuration
       | is extremely simple although it has some quirks. It also has a
       | few problems like not always correctly logging errors related to
       | CGI, and not being able to proxy to a backend over SSL.
       | 
       | I tried caddy because of its simple configuration syntax and
       | plugin support.
       | 
       | For caddy the sample webpage alone threw me off. It includes a
       | bunch of CSS, custom fonts, and for whatever reason it has tilted
       | text.
       | 
       | I'd like a test webpage to fit on my terminal screen when I SSH
       | to it. Or at least not require a modern browser to render.
       | 
       | Anyway I just don't think Caddy fits my usecase. Are there no
       | dead simple, lightweight alternatives to nginx and apache that
       | actually work?
        
         | orblivion wrote:
         | > I'd like a test webpage to fit on my terminal screen when I
         | SSH to it. Or at least not require a modern browser to render.
         | 
         | It sounds like it may be worth wading into it a little more if
         | this is what threw you off. Or is there some other reason Caddy
         | doesn't fit your use case?
         | 
         | It has batteries included, so it'll have some things that are a
         | little heavy handed or confusing. On balance I appreciate how
         | simple it is for a user at the end of the day.
        
           | Levitating wrote:
           | I might give Caddy another go. I just felt like Caddy tried
           | to be a bit more "modern" for my needs, I only need to
           | execute simple CGI scripts and forward requests after all.
           | And most "webpages" of mine are plain HTML.
           | 
           | Or the CLI that I dont't see myself use much I just
           | start/stop jobs with systemd anyway.
           | 
           | The builtin ACME support I could maybe use but I already have
           | some beautifully handcrafted cron jobs for renewing my certs
           | :) I even managed to more or less hack ACME support into
           | lighttpd using its config syntax.
           | 
           | Caddy actually used to have a very minimal test page, I think
           | they changed it with v2.
           | 
           | I really though lighttpd was perfect for me, very simple
           | unix-like daemon that just requires a config file to run. I
           | wish lighttpd v2 was still in development.
           | 
           | In any case I will probably give Caddy another go and
           | otherwise switch back to nginx. Lighttpd has been giving me
           | too much problems in production, like not correctly logging
           | CGI errors, and crashing when the configuration mentions a
           | hostname that cannot be resolved. Or even when testing simple
           | CGI setups, getting errors to show in stdout requires setting
           | /proc/fd/2 as the error log file...
        
       | 1oooqooq wrote:
       | i maintain both caddy and trafficserver.
       | 
       | traffic sees dozen of security releases a year... and i always
       | wonder if its less secure or is more secure because people do
       | find the holes there.
        
       | aborsy wrote:
       | I switched to Caddy from nginx and Traefik, and never looked
       | back.
       | 
       | Why do I need to write a lot of code to say map example.com to
       | 1.2.3.4?
       | 
       | I get there are headers etc, but in most cases, it should be just
       | one line, with sane defaults. That's what caddy does. Takes care
       | of SSL automatically, and does the job with minimal code. If you
       | have a special setup, there are options, and you can write more
       | code to achieve that.
        
       | meander_water wrote:
       | I'm surprised no-one has mentioned the admin API [0], which imo
       | is one of the main differentiators of Caddy. I've used it to
       | dynamically change the config without any downtime.
       | 
       | [0] https://caddyserver.com/docs/api
        
         | jsheard wrote:
         | Nginx does have something similar... but it's one of the
         | features that is exclusive to the paid version. Likewise with
         | other features like active healthchecks, which are supported by
         | both, but paywalled in Nginx.
        
       | samgranieri wrote:
       | I'm using caddy as a proxy to various services running node,
       | ruby, or elixir. It's replaced using mkcert and nginx, and I have
       | just about everything i need proxied to _._.localhost, with caddy
       | 's awesome Step-CA derived certiifcate libraries providing the
       | fun
        
       | iloveitaly wrote:
       | Caddy is really great. In prod, but most surprisingly for all
       | environments.
       | 
       | - There's a great tool, localias, which uses Caddy for a local
       | dev server https://github.com/peterldowns/localias
       | 
       | - I use it locally for dev https://github.com/iloveitaly/python-
       | starter-template/blob/m... which aligns tricky bits of a web app
       | like HTTP redirect, cookies, and CORS to work consistently across
       | dev and prod.
       | 
       | - Can be used on GHA for HTTPS as well
       | https://github.com/iloveitaly/github-action-localias
        
       | qwertox wrote:
       | > With On-Demand TLS, only Caddy obtains, renews, and maintains
       | certificates on-the-fly during TLS handshakes. Perfect for
       | customer-owned domains.
       | 
       | Does it allow to plug-in into this system so that post-renewal
       | actions are possible, like distributing those certificates to
       | other machines through Python scripts?
        
       | heraldgeezer wrote:
       | Im old. Why would I trust this over Apache and NGINX? Ive never
       | heard of this. Is this for local dev or to run actual bigger
       | sites?
        
       | braebo wrote:
       | I love caddy! I use it to serve webapps and APIs on my hetzner
       | boxes.
       | 
       | I hate the config file though. It could be 10x safer / more
       | discoverable / nicer to use by just using json with a schema that
       | validates and shows docs in the tooltips similar to tsconfig.
       | 
       | I suspect my typescript lsp addiction and relatively limited
       | (though non-zero) backend experience has spoiled my tolerance for
       | the primal nature of backend tooling.
        
         | FjordWarden wrote:
         | But it does support json for config files, you can even upload
         | them to and endpoint to change your config at runtime. Dunno if
         | it has a schema.
        
       | jbverschoor wrote:
       | Or just use orbstack and get https for free
        
         | lurking_swe wrote:
         | i love orbstack for personal projects but it's not free for
         | commercial use. FYI.
        
         | mikeshi42 wrote:
         | Caddy isn't just for local docker-based mac development - I use
         | it for any small project hosted on a linux VPS for example.
        
       | sebiw wrote:
       | My two cents having a respectable amount of infrastructure ops
       | experience: Use Caddy to get going quickly and to get a solid
       | setup with minimal effort. Use Nginx if you know what you're
       | doing and want full and deep control over the web server / proxy
       | layer of your stack.
        
       ___________________________________________________________________
       (page generated 2025-02-16 23:00 UTC)