A small network of sites does not need a small network of servers. I serve more than one public hostname from one Next.js application on one Mac. The hostnames read different brands because the content classifier looks at the topic and the tags of each article and sends the page to the right apex. The build is shared. The processes that answer HTTP are separate, so a restart of one brand does not have to be a restart of the others, and a failed build must not restart any of them.
That last rule is the one people skip. They edit a markdown file, run a build that dies halfway, then restart the live process out of habit. The live process comes back on the previous successful build if you are lucky, or it comes back broken if the restart races the failed compile. The correct order is dull. Check that the disk can hold the compile. Compile. Look at the exit code. Only then restart.
Why the disk check comes first
A Next.js production build of a site with a large catalog is not a small write. It wants several gigabytes of temporary files, and it wants them on the same data volume that already holds models, browser profiles, and the catalog itself. When that volume is under about eight gigabytes free, the build is how you fill the disk the rest of the way and take the machine down with it. The article can sit on disk as a file. The public site can keep serving yesterday's build. Those are both acceptable. A full disk during a compile is not.
I treat eight gigabytes as a hard floor, not a suggestion. If the volume is under it, the new article waits. Freeing space means caches and old logs, not the models the other jobs still need, and not a second copy of a catalog that is the source of truth. After the floor is cleared, the build runs once. It does not run in parallel with another build of the same app. Two compiles writing the same output directory is how you get a green exit code and a corrupt page.
One classifier, three front doors
The articles live in one content directory. A post is not "on" a hostname because of the folder it sits in. It is on a hostname because of its frontmatter. A strategy essay with no infrastructure tags belongs on the creator brand. An infrastructure essay tagged for self-hosted work belongs on the sovereign brand. A music essay belongs on the music brand. Getting this wrong is quiet. The page returns HTTP 200. It is simply the wrong 200, on a domain whose readers did not ask for that subject, and whose other pages now look inconsistent in a search index.
So the frontmatter is part of the deploy, not a decoration. Topic and tags are chosen so the classifier's order, which checks the athletic brand first, then the sovereign tags, then genealogy, then music, and only then the creator default, lands on the intended apex. A sovereign essay that also wears a music tag will never reach the sovereign host. The tag wins earlier than the author's intention.
Restart only the processes that finished
After a clean build, each hostname's process has to be kicked so it loads the new output. Kicking them before the build finishes serves the old output and teaches you the false lesson that the article is live. Kicking them after a failed build can replace a working server with a partial one. The check is the exit code, not the presence of the new markdown file. Markdown is an input. The running server reads the compiled output.
I also do not stack a heavy model job on top of the compile. Unified memory on a single Mac is one pool. A language-model server that is already holding several gigabytes, plus a webpack compile, plus a browser automation tool, is how the machine starts compressing memory and then killing processes that looked idle. The compile is a guest. It should be the only heavy guest in the room.
What "live" means
A file in the content directory is not live. A successful compile is not live. Live is an HTTP 200 from the public hostname, with the new title in the HTML, after the process has been restarted onto that compile. Until that request returns, the honest status is "written, not shipped." I would rather say that than send someone a URL that 404s.
The same honesty applies to a news desk that is switched off. A draft that the config says must not be public stays a draft, even if the article is good. Shipping it would be a second decision, made by hand, not a side effect of wanting the page to exist. The build can contain the draft. The hostname should not admit it.
FAQ
Can three brands share one repository?
Yes, if a single function decides the brand from frontmatter and each hostname runs its own process against the same compiled output. The repository is shared. The restart is not.
What should I do if the build fails?
Leave the running processes alone. Read the error. Fix the input. Build again. A failed compile is not a reason to restart, and it is not a reason to start a second compile on top of the first.
Why not give each site its own machine?
Because the scarce resource is attention, not computers. One build, one classifier, and a disk floor you actually respect will outrun three servers you forget to update. Add a machine when the memory pool is the bottleneck, not when the markdown feels like it deserves one.