The web server deployment model breaks at hobby scale

57 pointsposted 5 hours ago
by meetpateltech

61 Comments

SlavikCA

4 hours ago

I have 5Gbps fiber at home. LAN is mostly 10Gbps.

I'm hosting few hobbyist public websites. One is the library of hymns, songs, ... - mostly PDF, MP3, MIDI.

OpnSense router -> Traefik -> Docker container.

That Docker container runs on NAS, which is connected via 1Gbps port.

Suddenly, last week I started to get over 1000 RPS. Was it scanner, parser, crawler, DDOS? I can't tell, as user agent was default Mac OS.

It was using ~1Gpbs bandwidth. From many IPs. If I would have it hosted at AWS / Azure, it would cost me > $40 / hour for the bandwidth. Unless I use some of their CDN.

My router CPU went high, but it handled it ok. NAS CPU went high, but it handled it ok. Traefik loaded the server heavily: it had to both receive and send 1Gbps. And write access logs for all requests. My Alloy & Loki logging system got loaded heavily.

NAS already have cache. I tried to enable cache on Traefik. It went OOM in 2 minutes: https://github.com/darkweak/souin/issues/844

When I searched, I found that Traefik cache with proper memory handling is available only in Enterprise version.

Solved the issue by putting the site behind Cloudflare proxy and enabling it's magic to protect from the bot.

smashed

5 hours ago

I can relate to the TLS termination issue. It is difficult to provide a self hosted version of a web app with a sensible TLS setup.

The best is almost not to do it at all. Just have a docker image serve http/1.1 and document that a reverse proxy is required to expose the service.

There are simply too many ways to do it and every sys admin/hobbyist has their own preferred way.

For the anonymous and authenticated caching issues the author goes into, I think once again it is useless for self hosting. Just embed a performant web server like nginx for example that is pre configured to serve static files. Use proper headers, and predictable/simple paths. Self-hosted versions are going to be low traffic and just need to work.

Have advanced settings for more control, but keep the default simple and working out of the box with minimal dependencies.

smw

4 hours ago

I don't know what you're on about. Just run Caddy and it does it all for you.

smashed

4 hours ago

That is exactly what I am talking about.

You say caddy. The next person will say nginx-proxy-manager. The next will say DNS challenge let's encrypt behind wireguard VPN. The next will say Traefik. The next will say CloudFlare tunnels.

Everyone has their preferred solution and its always the best and simplest.

dpoloncsak

an hour ago

Just commenting to represent the NPM referrers that you mentioned, since it seems most HN users are Caddy enjoyers

dsvf

4 hours ago

As a one-person-scale selfhoster that has wrangled Apache and nginx before, I'm also saying go for caddy straight away.

smithniels

4 hours ago

As the next person on this post, I second Caddy

smashed

4 hours ago

Ok I'll bite again.

Do you want a caddy service embedded with every web app you self host or are you running a single one serving all your apps?

From my understanding if you want acme http challenges to just work with let's encrypt you probably need to use a single, separated caddy to front all your apps.

In that case if I ship a caddy service pre configured to do TLS termination with my app it's just more trouble for you no?

dsvf

4 hours ago

Fair enough, http is enough - I anyways have one caddy to rule them all. However, if your app is picky about reverse proxying, e.g. headers, please add a sample caddy config. It's often the first thing I'm looking for if I'm trying out a tool and want to host it under a subdirectory before configuring a subdomain.

sam_lowry_

2 hours ago

No, HTTP is not enough, I submitted a couple HTTP-only links to HN lately, they got flagged within half an hour, even HN crowd can not open HTTP links anymore ;-)

sam_lowry_

2 hours ago

I posted this in a sibling thread, but it's also appropriate here.

I self-host Immich with Caddy, and it's complex, really.

Caddy runs in podman compose next to Immich, there are firewall rules to allow traffic in and out and proper dependencies in custom systemd units in case podman networking goes bust after firewall rules are reloaded and a readme that covers all that.

Exactly the point OP is making.

chillfox

4 hours ago

Just provide a docker compose file.

greatgib

3 hours ago

What it shows is that there are a big number ofeasy options if you want to.

horsawlarway

3 hours ago

Nah he's entirely right. Serve http, let the user do https.

If you want to put caddy in front of yours? Great it works.

For me, running a much larger setup? Great, it also works.

For users who never expose it beyond an IP address on lan? Great it also works.

egberts1

14 minutes ago

That is why my webserver only server-negotiate Cha-Cha/Poly at TLS level and rejects all else.

No caddy. No cache. No proxy.

A lot of scrapers give up.

Log rate remains low. Actual visits even lower.

Peace of mind, for a while:

https://egbert.net/blog/articles/index.html

lee_ars

4 hours ago

> You document what needs to be reverse proxied and give examples for caddy and nginx, repeatedly cursing at nginx for not having an if that’s useful.

Somebody hasn't read the docs and doesn't understand how nginx's "if" works, because it's fantastically useful.

turtlebits

4 hours ago

At hobby scale, you don't have to care about the details. Just ship a zip or container image with docs and let the user figure out the rest. Self hosting is going to require some bit of expertise.

I personally don't like apps that ship the entire sink (complex stack) when I already have an opinionated setup that already includes TLS/access control/etc.

scaryclam

3 hours ago

I really wish people would tell me what the dependencies are and NOT just ram everything into a container image so I have to reverse engineer what's required to just run the damn thing on the stuff I am ALREADY running.

Just tell me what the entry point is and what the dependencies are for it so I can decide if I already have enough to just sort it out myself.

By all means, create a kitchen sink container image as well, but don't have that be the ONLY artifact for running it.

bradly

5 hours ago

I'm not sure I understand this post. Is this talking about self hosting Caddy in a home lab setting or just static web hosting on a VPS?

tingletech

5 hours ago

I think the author is distributing a web app that is run by hobbyists with a lot of esoteric home labs?

mikepavone

3 hours ago

Sounds like they've worked on some ActivityPub related software based on their other blog posts and codeberg.

The details remind me more of the Bluesky PDS though. It's nodejs-based and the only officially supported way to run it is via a largely self-contained docker container.

sam_lowry_

5 hours ago

I think the author missed the root cause, which is the demise of (unencrypted) HTTP/1.1 connections.

josephg

4 hours ago

I'm glad unencrypted http/1.1 was deprecated. I want a privacy online. TLS also gives you much better data integrity guarantees. Some ISPs - particularly in the US - actively inject javascript code into websites served over plain HTTP.

I just wish nginx / caddy / etc had better out-of-the-box support for letsencrypt. It would be way easier to set up if it was just built in to nginx. Let me specify my domain in my nginx config, and just make it work.

sam_lowry_

3 hours ago

Look at this from the Digital Sovereignty angle.

AFAU Let's Encrypt gets its money from Google. There are other minor providers of similar services over the ACME protocol, but this does not change the fact that they issue the the majority of the free TLS certificates.

We already had one centralized domain name system managed by the US Government that we have to hop through before publishing our content online for everyone.

Now, we silently and tacitly added another US-based one.

deltarholamda

5 hours ago

It's partially about how complicated modern Web services can be, and why so many people just give up and ship a Docker container. It's also about how agonizing over the details is sometimes just wasted because all of your users are just AI scrapers.

An art professor I knew used to say about overwrought paintings "too much sugar for a dime". Technical people are often prone to this as well.

bradly

3 hours ago

Thank you. This makes more sense. I have an open source web app and it uses Docker (Kamal specifically) to make it easy for others to deploy.

ComputerPerson

5 hours ago

I host a webserver for a living, so I might be too far removed from the problem; I don't see anything that 1 minute of effort as part of a less-than-10-minute session with an agentic AI tool can't solve safely. A decent README and project structure is all Codex/CC/Pi needs. I mean this even for the least-technical person who would be self-hosting something.

I guess that breaks the plug-and-play nature, but you can't expect something internet-facing to be plug-and-play. (Maybe that's the real travesty here.)

user

5 hours ago

[deleted]

andai

4 hours ago

Was this written by the Department of Demoralization?

TacticalCoder

3 hours ago

Such defeatism indeed. I understand that things look complex but plenty of very complex apps can be self-hosted and they Just Work [TM]. Now, sure, there's work involved. But, just like many others, I can run Plex, JellyFin or Immich just fine and those are more complex than 99% of all webapps ever shipped.

We'got all the world's knowledge compressed and queryable with LLMs: there are way less configuration issues that I cannot solve today than used to be the case.

Did those in charge of those standards royally fuck up HTTPS/TLS? Of freakin' course they did. The interests of the big players, not the small ones, have been taken care of. And the result is an ultra complex mess of fucktarded standards.

But it is what is: it's what we have. And we'll make it work.

KronisLV

5 hours ago

> Deployments not using Docker will no longer be supported.

This is the way (while also allowing people to use their own proxies etc., but being clear about those not being officially supported).

Ship your back end container, your front end container, tell people how to set up the off the shelf DB containers or whatever else your software needs and if you don’t need 20 different components like Sentry self-hosted versions do, you’ll be fine. The DB can be a container or not. The reverse proxy can be a container or not. Hell, if someone wants to build the back end or front end from source and serve them differently they can, just on their own time. That’s pretty close to the 12 Factor App principles.

Just avoid a lot of complexity when possible: do traditional SSR, or with some progressive enhancements or what I like to do in this day and age (unless maximum accessibility is paramount) only use your back end for the API and have a traditional SPA, none of that complex Next.js stuff. Your front end just becomes a bundle of files that you can put in a web server container to be proxied by whatever the ingress is. At most the Docker entry point would change some values in config.json that the app loads on startup in the browser.

If someone asks for Kubernetes support or whatever, just wish them the best of luck in setting it up themselves!

snowwrestler

3 hours ago

Lots of things break at hobby scale, mainly because hobbyists can have a huge range of experience, expertise, and willingness to do things themselves.

Anyone serving hobbyists, commercially or on a volunteer basis, needs to accept that there will be some number of hobbyists “below the line” of what you can reasonably support. Those folks will just struggle with what you can provide to them, and you will never be able to address all their complaints, concerns, mistakes, etc.

You just have to mentally cast them free on their own. At most, encourage them to find fellow hobbyists who can help them level up where they need to in order to engage with your offering.

iamcreasy

2 hours ago

Interesting read.

> you see that the reverse proxying rules you would need are more complicated than usual. you can’t Simply forward /api to your application and the rest to the frontend due to various reasons outside your control.

If the author is reading: Can you elaborate on what reason you are referring to that are outside my control?

glaslong

4 hours ago

I literally just sent some friends a docker image and told them to point Luna at it, for which they were set up in ~20minutes and $3 of tokens, so I'm skeptical.

My homelab is also currently ~40 nix service VM's plus a handful of Ubuntu, etc long tail, and some external DO droplets for NAT, and a more robust vlan config than I'd ever been able to put time towards before... which I haven't had to do more than a dozen hours of manual setup on IN TOTAL thanks to Fable, Sol and local Qwen.

There's truth in this post, but I doubt it's longevity.

KnightHawk3

4 hours ago

Why split the nix into so many VMs instead of just systemd units?

glaslong

3 hours ago

They're not all tooootally atomic, I have clustered things like libation+audiobookshelf, ollama+ds4+litellm, but I like that I can manage things almost entirely at the network and host level, generally atomically per service, and especially between services (eg homeassistant and the local ai).

It's DEFINITIVELY overkill, and fills up fast, but nix making everything near fully declarative to roll fwd/back or shuffle between proxmox hosts at any time makes for a clean and easy mental model. Both for me and the AI, because it can infinitely retry a nix flake config until it gets it perfect.

lee_ars

3 hours ago

Sounds like a poster child for LXC containerization with Proxmox — all the host-level management of a non-ephemeral VM (including snapshots!), without the every-machine-has-its-own-kernel overhead.

glaslong

2 hours ago

I do have a couple LXC for the things that need tight GPU control. Ollama and DS4 permanently, and an ml-workbench that steals the 3090 from my Cachy gaming VM when I get it in my head that I could try implementing some cool gsplats paper haha.

I could definitely slim things down without disko, virtio, etc, and especially whole separate kernels.. but it's also not such a huge diff that I mind. I'm not adding new services all that fast anymore now that I've got my basics + wishlist set up, so I'll grab another box from the local pc recycler if I ever need space for another ~30 VMs some day rather than when I need space for another ~40-50 LXCs.

And in the meantime if OpenAI publishes a scary brag about how GPT-7 popped a shared kernel on accident I can be relieved that my private bookmarks repo isn't vulnerable while the internet burns down.

wainstead

4 hours ago

> you have enough interactivity to warrant a single-page-application as your frontend. however, you also want people without javascript enabled to be able to read the bits that don’t require interaction.

I think at this point it's not a hobby, it's a burden.

ctoth

2 hours ago

At hobby scale, why aren't you using Dreamhost + Php for the dynamic bits like we did 20 years ago? It still works!

axus

4 hours ago

These all seem useful warnings to me, I'm vibing something for hobby scale. The installation script was the one place I needed to reorganize and make a lot of human-powered changes. And I haven't even distributed it yet :)

horsawlarway

3 hours ago

Most of these problems are actually solved with containers, though.

An opinionated release of k8s (k3s, microk8s, etc) does wonders for making much of it just disappear.

You pay a slightly higher up front cost in complexity, in return for largely removing absolutely all the listed problems in this blog.

If you're going to run more than just one app... It's the route I'd recommend.

I think the market is already moving here, too. Synology is exposing very easy interfaces to run container workloads on their devices.

I think we're headed towards something like a combo NAS/router that handles storage and networking (by far the hardest parts of hosting).

JodieBenitez

4 hours ago

Damn, what a downer...

Hobby scale you said ? It doesn't have to be that complicated.

sam_lowry_

5 hours ago

This is only tangentially related, but I have a love-hate relationship with Immich. Love for everything, but loads of hate for the bug-o-feature that disallows sharing of albums if the website is not hosted over HTTPS.

I can fiddle with the page content in Developer Tools to make it work, but frankly, WTF, especially since Immich expects people to set up a reverse proxy for HTTPS access on their own and does not help them in any way (like providing a pre-configured caddy in their compose.yaml, I don't know)

AussieWog93

5 hours ago

Honestly, this is a problem that has been solved by LLMs. Just point Claude Code to the server over SSH and say "We need Immich to be served over HTTPS".

You could theoretically upstream the fixed compose.yaml if you felt like it, but the project seemed unusually hostile towards the one fix I tried to upstream.

smw

4 hours ago

Here's the entirety of the Caddy config to reverse proxy something with managed tls certs. I feel like it's not that big a deal?

  photos.example.com {
          reverse_proxy 127.0.0.1:8080 {
                  header_up X-Real-IP {remote_host}
          }
  }

crtasm

4 hours ago

caddy passes on the source IP by default so it's even easier than that

    photos.example.com {
        reverse_proxy 127.0.0.1:8080
    }

the immich documentation covers this as well as nginx, apache and traefik https://docs.immich.app/administration/reverse-proxy

sam_lowry_

2 hours ago

Heh... I self-host Immich with Caddy, and it's more complex, really. Caddy runs in podman, there are firewall rules to allow traffic in and out and proper dependencies in systemd units and a readme that covers all that. Exactly the point OP is making.

All because we forced TLS on everyone instead of solving the JS injection problem in some other alternative way. Like... legal, maybe?

user

2 hours ago

[deleted]

skydhash

5 hours ago

All of those requirements seem weird. I selfhost a few software and the user count is one. My extent at sysadmin is to write a systemd service, configure the proxy (if it’s on a vps and I use subdomains), and maybe use ansible for scripting the provisioning and deploy.

It’s fine to publish recommendations how to tune configurations for specific usages. But I only need the app, not the various things that you may think I need. And I really want the app to only solve its essential problem. It should not take care of the IT part other than providing configuration samples.

jermaustin1

5 hours ago

And I do `docker compose up` now with a caddy server in front of docker, so I can just add a new site (sub domain or directory) that reverse proxies to that docker container's port. And the beauty is, that I have a skill for it for claude code, so I actually don't have to do any of that for my local self-hosted stuff.

I just call /publish-local-docker subdomain.mydomain.local

And if there isn't a docker compose, it will create one, and then run it, and update caddy server on its own.

micromacrofoot

4 hours ago

I get more blind visitors than visitors with javascript disabled these days

scotty79

5 hours ago

How many of these problems PHP solves out of the box or makes irrelevant?

marcosdumay

4 hours ago

It solves static files... If you are extremely careful to set the executable properties of your PHP scripts.

No other.

tommek4077

5 hours ago

All. People forget hiw performant the LAMP stack is.

vehemenz

5 hours ago

It feels like there could be an entire longform piece on how "modern" web development norms arose because hobbyist/student web developers learned everything in an ad-hoc, local environment without access to, you know, a development server or a mature software stack.

andai

4 hours ago

There's an easier solution. Just don't have private data. Then you don't need SSL either.

Unless you also want to deal with security, backups, GDPR compliance, etc.

Dotnaught

5 hours ago

Perhaps the article's title should be, "The web has become a hostile, largely automated environment and naive hobbyists may find it difficult to coexist with professional scrapers, scammers, grifters, bots, hucksters, and cybercriminals."