This is the backstory for reverse-bin: My Retro-Futuristic Successor to CGI-BIN.
In the early 2000s Linux was cool, corporate types used Windows and kids were learning Linux. Linux systems were multi-user and ~/public_html was the way to publish a static website and one could do some backflips with apache config to get something similar for dynamic websites using PHP or general-purpose cgi-bin.
cgi-bin
cgi-bin was the simplest possible way for any web server to launch dynamic apps. HTTP headers would get translated to environment variables and stdout into your response, it was dead simple.
I found this technology interesting because it allowed one to start something in a scripting language and then transition to C++ when performance was needed. An amusing aspect of cgi-bin process-per-request lifetime was that if you fucked up your C++ memory management, the next website hit would start from a clean slate.
I also used a high performance language like OCaml with cgi-bin when I wanted to do complicated things fast and without hard-to-debug bugs.
There was no SSL (it was expensive), one domain (those were expensive), test-driven development wasn’t popular, it was ok to edit code on a production system (so also no CI/CD), responsible people like myself would even use CVS to edit-in-prod ‘safely’.
Oh, and this ran everywhere, I started on an ancient-at-the-time discarded 386 and eventually moved to hosting my stuff on a WRT54GL.
Linux became corporate, VMs made servers cheap
Suddenly one no longer had a single giant Apache server. Everyone had a VM and there was some giant reverse proxy to tie all the VMs together. Deploying new apps would involve asking the sysadmin managing the big server. It was no fun to ask a very busy human to add a new (and thus unimportant) app.
Then Lambda and Kubernetes made stuff somewhat self-serve, but now with lots of Docker and yaml and slow-ass CI/CD. Suddenly this became universal: even when the goal was to write web apps for fun, one would inadvertently be role-playing being at work. Yuck. I feel like when “my Linux server” got renamed into “home-lab”, that was more of the same.
The weird somewhat cool corporate dev env
Among the corporate horror there appeared an overgrown JS-based CDN and I thought it had the same lightness as cgi-bin and I even wrote a blog post about it. But it turned out to have some downsides:
- One has to use an unusually poorly supported flavour of JS. Eg when I discovered the super-cool duckdb, I had no sane way of using it on cloudflare. I wasted a lot of time rebuilding it using the wasm flavour cloudflare liked and failed.
- Cloudflare would break stuff for reasons outside of my control.
val.town and smallweb.run era
val.town opened my eyes to the fact that as of ~2023 it was still possible to write quick apps in a fun way. val.town introduced Deno into my world, and Deno broke my brain: being able to declare dependencies inline made for super quick experiments (uv has that feature too). I still couldn’t use duckdb sanely there and it felt weird to version code on val.town. val.town was/is a naughty modern equiv of the ’edit-code-in-prod’ 1990s feel.
Then I discovered smallweb.run. pomdtr made a genius contraption. It was a dynamic reverse proxy fronted by cloudflare tunnel that would dynamically launch sandboxed deno apps using a nasty let’s-find-an-available-http-port and launch/shutdown apps on-demand hack. This thing also could not run high performance code or duckdb due to sandbox restrictions…but this was code running on my computer so I could hack around it. I really learned to appreciate the power of a sane sandbox provided by deno and configured out of the box by smallweb.
Then I tried to use smallweb.run at work to enable quick experiments and realized that the reason web servers are so configurable is that every web server must adjust to whatever social conditions it operates under. It was a weird success: coworkers were at first offended at the absence of docker and then very happy to never think about docker and ci/cd. However, it was needlessly limiting to restrict oneself to easy web dev using Deno and then host various awesome golang software using kubernetes.
So I loved the safety and ease of use of smallweb, but I was bothered by the lack of flexibility to run non-deno stuff and no clear opinion of how to do this in a multi-user env.
Which is how I ended up writing reverse-bin.