Part 4 of 5 in the Self-Running Channel series. New here? Full intro at the end.
TL;DR
The channel dashboard is one generated HTML file behind a small Cloudflare Worker and a serverless database. Zero servers.
Mostly read views, one write path. A button tap at lunch becomes a scheduled post the same evening at 17:00.
The two render machines sync through object storage, like a shared drop folder.
I wanted to run my video channel from my phone. See the queue, watch the latest renders, check yesterday's views, and push a new reel into the schedule with one tap.
The obvious answer was a small web app. I built a static page instead, and I want to defend that choice, because it keeps coming up in my projects.
Written down, the dashboard needed four things. The publish queue with dates and statuses. The newest render of every pilot as a playable video. A link to each storyboard. And a performance table once analytics existed.
That is four read views. The only write the product really needed was "add this pilot to the queue." A few more buttons accumulated since — reorder, re-render, hide — but they all ride the same path as that first one.
Read-heavy with a handful of writes is the profile of a generated page, not an application. So the dashboard is a Python script that renders one dark HTML file and uploads it to object storage. The page pulls fresh queue state when it loads, and the file itself regenerates after every render and every daily publish.
There is no server to patch and no framework to upgrade. The hosting bill is zero.
A tiny Cloudflare Worker sits in front. It gives the page a proper domain and keeps the rest of the storage bucket unreachable. The first version was 44 lines.
It also handles the writes. In the first version, the "add to queue" button posted to the worker, the worker dropped a request file into storage, and the PC picked that file up before the next publish run. When I wanted reordering, the queue moved into Cloudflare D1, a serverless SQLite, and the worker grew to about 250 lines. Same shape, better ledger, still nothing to host. Either way, a button click at lunch becomes a scheduled post the same evening at 17:00. Latency measured in hours, and for this product that is fine. (I wrote about the same small-worker trick when I replaced a paid webhook service with a Cloudflare Email Worker.)
Renders happen on two machines. The home PC does most of it, and for a while my Mac composed some reels through a cloud GPU. Videos are too big for git, so each machine only has its own files.
The first dashboard version quietly showed only whichever machine built the page last. The fix was to treat storage as the meeting point. Every build mirrors its local renders up and checks what the other machine already mirrored. The publish task can even pull a missing video down from that mirror if the file never reached the PC.
Same trick for analytics. The PC can reach the database and the Mac cannot, so the PC leaves a stats snapshot in storage and the Mac rebuilds the page from the snapshot. This is the two-machine split I keep hitting since I stopped running my side project on my own computer.
None of this is clever. It is the old pattern of a shared drop folder, wearing modern clothes.
It replaced what would otherwise be a VPN, a database connection from two networks, and an API layer.
I did consider a hosted static site with git-based deploys. Two things killed it.
The data that changes daily is queue state, videos, and stats. None of it belongs in git. So every update would need a deploy pipeline run for content that never touches version control anyway.
And my hosting provider for another project has a monthly deploy quota. I have already exhausted it once this year, which taught me not to spend deploys on things a file upload can do.
The whole dashboard, worker included, took one evening. The stats section appeared a day later, when the analytics collector started writing snapshots. Total infrastructure added to my life: zero servers, one worker, one PIN-protected write path. It is the same instinct that made me ask Claude to build my infra dashboard rather than stand up another service.
Want this stack without building it?
The first iteration of this publish stack — queue, dashboard, worker, YouTube Shorts and Instagram Reels publishing, and the analytics collector — is exactly what I packaged into Faceless Channel OS on Gumroad. Bring your own videos, point it at your channel, and it runs on any machine that can execute a Python script. It ran my channel for a month before I wanted anything more. $39.
If you have ever deployed a full app to serve four read-only views, you know the itch this scratches. Restack this if it saves one person a needless deploy.
This is part four of a five-part series on running a faceless video channel as a solo maker. The last post is the one I cannot write yet: thirty days of real numbers against the forecast from part one. The spreadsheet said a 45 % chance of "nothing much happens." We will see. Subscribe if you want that scorecard when it lands.
P.S. The PIN-protected button is the only thing standing between me and a stranger queueing reels to my channel. So far it has held.
Hi, I’m Daniel — a software engineer, solo builder, and the person behind Digital Craft Workshop.
I’ve spent ten years writing TypeScript, .NET, and React for a living. The last few of them I’ve been building on the side of the day job: AI video tools like the Reel Pipeline Kit on Gumroad, Reads in Motion — reels made from other writers’ Substack posts — and a history reel channel that publishes without me touching it. Some shipped. Some I killed. Both are useful.
Digital Craft Workshop is for developers, AI builders, and indie founders who’d rather understand the craft than ride the hype. The kind of reader who distrusts gurus and wants AI that’s cheap, practical, and accountable to one engineer in a workshop.
Each essay is something you can read in one sitting and use the same week: an architecture pattern, an AI workflow a single developer can actually run, a build log, or a postmortem on a project that didn’t make it.
Everything here, I actually ran — including the parts that broke.
No posts

Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.