Hacker News new | ask | show | jobs
by cj 1330 days ago
Static hosting combined with server-side dynamic content modification using postgres was the interesting part for me.

Static hosting has historically been seen as exactly that, static and immutable.

Things like Cloudflare functions/workers can turn static hosting into dynamic content delivery while maintaining (most of) the benefits of static hosting.

Granted, this can be done whether the underlying content is hosted on Cloudflare, AWS, or a server in your garage so long as it’s proxied/CDN’d by a service like Cloudflare or Cloudfront+Lambda@edge, etc.

5 comments

Yes, it's great because static/static+some dynamic bits fits a lot of use cases and it's quite simple to deploy, manage and maintain.

It's nothing that new though, Firebase (part of GCP) and Netlify have had that for years. CloudFlare just have the right combination of marketing, reputation, pricing and tech to make headlines with it again.

> Yes, it's great because static/static+some dynamic bits fits a lot of use cases and it's quite simple to deploy, manage and maintain.

Do you have some examples? I always get excited by this serverless stuff, but often the use-cases are quite limited if you think about it, or maybe I’m thinking wrong, especially if you take vendor lock into consideration.

Small Things I used it for:

Contact Form - Comments System - Authentication System - Image resizing (thumbnails) - GraphQL Gateway (working on this now) - Bypass CORS - Generate a random number on the server

I also built full apps on CloudFlare workers (and doing it now).

Only one caveat: They are heavily invested in marketing but their tooling is real cr*p. They are not investing in the Rust integration; or the more regular tools/integrations you are used to.

This comment is about serverless in general, not this particular tech. I’ve been abusing serverless for three years now using a NestJS bridge to the API gateway. All API request get bulk routed to a single lambda. NestJS, a dependency injection system for Node, handles particular routing, JWT validation, etc. Then my code does all the backend stuff. If I ever need to move from AWS lambda to EC2 (due to payload size or sync call limitations), I can. Neat JS will boot normally. Little to no vendor lock-in, especially in the domain later thanks to Clean Architecture.
A simple usecase I had was submitting a contact us form from a static marketing site and being able to route it somewhere.
I have never seen an example where you land a JS file in a static website in git and it just runs as part of server side middleware. Seems legit novel but would like to know other examples.
That's not middleware, is it? It's cool, but sits between what is discussed here and something like a FaaS. My understanding is that this post is about actually deploying middleware that runs during the serve of the static pages.
They have this kind of middleware as well: https://vercel.com/docs/concepts/functions/edge-middleware

Don’t know if it’s as powerful, though — haven’t personally used it.

Firebase Cloud Functions: https://firebase.google.com/docs/functions/get-started

You drop a file in the functions dir of your repository, edit the firebase.js(on? it's been a while) config file to say that function X maps to path Y (so you can have api.site.com or site.com/api or whatever you want as a redirect to your function), and run firebase deploy.

That's FaaS, not middleware for the static contents of your site.
It's similar to what I was doing 10 to 5 years ago but in Perl.

Drop a file into a directory which is all or mostly static Markdown, HTML or CSS, but those files can contain markup to call other modules, as well as code files.

The existence of a file is enough for its index code to be run (if it has any) and any URL-set and page components it makes available are available to other pages to be used, or served as they are. A single file can offer many URLs, usually anchored at the name of the file but not necessarily. The reason it can affect URLs outside the name of the file itslf is that it's efficient to index all files in a directory tree, even on every HTTP request, if that's done by file change detection and the results are efficiently cached.

Some of those files act as filtering middleware, processing the input and output of some or all URLs and passing along what they don't change.

Updating static Markdown, HTML and CSS, dynamic content, code, and JSON data, are done by 'git push' or 'rsync', or just by editing files in place if you prefer. The server automatically detects file changes and keeps track of all code, file and data dependencies when individual things are used to calculate a response. The full dependency structure for each response calculation is recorded with each cached response.

Cached responses include both full HTTP responses, and components and data available for use in the manner of a subrequest. If a previously cached response depends on a file that has since changed, or been removed, or even a file that was previously absent but now present, or another cache condition such as a JSON or SQLite file change, or logged in user etc, the cached response is invalid and must be regenerated. Regeneration is a combination of on-demand and ahead-of-time, to be able to respond quickly with the speed of a static site for small finite page collections, while behaving correctly with large or infinite collections. Some code updates trigger a process restart because some code can't be safely unloaded or replaced; some code is fine updated, though, and this entire process is well automated. In practice, pleasant and fast to use: edit a file and see the result immediately on reload, with no compile/build step or extra actions.

The dependency structure partly reaches the browser, so that requests to cached responses can be served more efficiently, sometimes even zero latency. In some circumtances, changes in files cause events that ripple through to the browser causing real-time updates to components in-page without a refresh. The result of those is a little like Meteor or LiveView, except almost everything is made from static page files in Markdown or HTML, code files, and JSON data files, and the set of available pages (and "table of contents" pages) are built by indexing those files.

In practice it's mostly writing Markdown, and this is great for emphasis on content first. Or Markdown templates: content that varies a little according to data. But with extensions to be able to drop in useful rendered components (graphs, generated images, templated CSS, transclusions for headers/footers, etc) and dynamic components (live updating when the underlying data files are edited).

It even serves PDFs and thumbnails of those as in-page components, where the PDF content is HTML rendered by running Chrome on the fly from within an in-page component to generate the PDF or image, with Chrome told to fetch a subrequest which serves it the contents of that very same component. This makes for some pretty lists of downloadable PDFs, all generated from JSON data. This probably sounds complicated, but it was actually a fairly simple single file of code, dropped into a directory to make the component available by name inside the other Markdown quasi-static files.

One small VM served a few thousand requests per second last time I checked. Not as fast as a Rust server, but good enough for my uses. It made heavy use of Perl coroutines to serve and cache concurrently, and NginX to make routing and static-serve decisions. Perl coroutines are not commonly used (for ideological reasons I think), but they work very well.

I don't use the sytem any more, but it was the nicest I've used.

Cloudflare workers are distributed through hundreds of locations, and thousands of servers. Doing that with Perl would have been impossible. Also, remembering from my old CGI/PHP days, what usually happen is that the scripting language creep start getting bigger and bigger until it's unmanageable.

I'm not saying Cloudflare workers are a better proposition now. (their ecosystem is a complete shitshow) but the idea has lots of potential; and will probably be the future of computing[!].

!: That is, if the decentralized web fails to take off in the next 5 years.

> will probably be the future of computing

I think you're right, but I think the key part of the tech is economic: their ability to deploy hundreds or thousands of instances safely shared by large numbers of replicated sites and applications belonging to different site owners.

Individual site owners can't afford that level of infrastructure for each site separately. Actually deploying it isn't that difficult, it's just expensive and unjustifiable.

(I nearly started a business doing what Cloudflare Workers is doing now, about 10 years ago (and not with JS/Node), so I know a fair bit about building out this sort of distributed edge system, including the WebSockets and anycast part. But life took a turn and IPv4 blocks for anycast were starting to look a bit beyond what I could justify for the development, even back then. In retrospect it would have been a good thing to build.)

> That is, if the decentralized web fails to take off in the next 5 years.

You have given me an idea :-)

(For a side project I'm working on zero-knowledge proofs of execution, which allows nodes to execute code on behalf of other nodes without the latter having to trust the former. Performance is far too slow to run things like websites at the moment, but there are many tricks for speeding it up, including hardware acceleration.)

> Cloudflare workers are distributed through hundreds of locations, and thousands of servers. Doing that with Perl would have been impossible.

No, it wouldn't, that's a misconception. The Perl system I described ran fine on however many servers you wanted to run it on, like any horizontal scaling system. Pretty much anything that runs in a container and isn't required to communicate with a central database does. The design based around indexing files and caching calculations is effectively stateless; it scales without limit if you have the servers.

Any specific points of global data consistency require communication with a shared data store of some kind, but that's also true in Cloudflare workers, where there's a separate Durable Objects system for that. Cloudflare's Durable Objects is pretty good as those things go, but that's not what your comment was about.

What's impossible for most is paying the cost of hundreds of locations. And if you really want to do it well, anycast IP blocks. But if you have the servers, and don't need every request to fetch from a central database (or can use an eventually consistent distributed one), there's no problem deploying as many instances as you want with something that's effectively stateless, even if it's Perl, Python or PHP.

> what usually happen is that the scripting language creep start getting bigger and bigger until it's unmanageable.

Probably right, but I'm curious why you think there won't be equivalent JavaScript creep in sites using CloudFlare Workers.

I'm interested in why you think that their ecosystem is bad. I was going to tinker with it. Also, do you know alternatives in the space that are better?
This sounds similar to the old Server Side Includes [1] .

In the 90s I was using SSI to build dynamic, but static sites

-- header --

-- hierarchal javscript menuing --

-- content --

-- footer --

-- tail --

[1] https://en.wikipedia.org/wiki/Server_Side_Includes

SSI was my first introduction to abstraction in programming. What a rush!
I’m still struggling to understand how this is any different than an oldschool cms or blog with a cache in front.
It’s not. You can achieve the same or better results with Varnish. You can even achieve edge caching with Fastly (cloud varnish).

I think of it just as a different approach, where the focus is static (cache) with dynamic layered in as necessary. This forces you to be more explicit about dynamic behaviour and treating cache as a priority concern.

Having stuff served up near the user for speed, for one.

Also DX being better

no add + free.

Plus CDN if that matters.

This is exactly how we built Bluo: dynamic cms just like wordpress that deploys static assets (html,css,js,images) to cf workers.

Benefits are obvious: high reliability and speed to serve the static files. In addition, if the cms server is down for whatever reason, your website is still live and working fully (not just cached pages, all of them) just fine.

Actually you can think of it like a pre-built cache that it’s deployed to cloudflare kv store.

Other cool features we have is real time collaboration in the editor.

Check more about our architecture decisions here: https://bluocms.com/cms-cloudflare/

Went to the website and there is no pricing, no signup/login whatever ?
You can contact us by email if interested.
Can you explain how Cloudflare Workers factor into hosting static pages on Cloudflare Pages vs hosting a React SPA on pages that talks to any other API?

Like are the workers just serving as your backend at that point? Or are they doing something more or different as well?

the workers are regenerating the static site on postgres push
Ah, so still fully static vs. a SPA that uses REST or GraphQL. So then clients interact with it as static HTML/JS rather than hydrating it via Javascript.
yes exactly