Right now, every domain serves from the same flat directory: /mnt/public/.
This means 1.foo/deck, 3.foo/deck, flawless.engineering/deck, and 1234567.foo/deck all serve the exact same file. There are ~170 files in /mnt/public/ โ all of them accessible from every domain. There's no separation. No isolation. No identity per domain.
The only exception is drip.xxx, which already has its own root at /mnt/public/drip-xxx-site/.
Each domain gets its own subfolder in /mnt/public/, named after the domain itself:
/mnt/public/ โโโ 0.foo/ โ serves 0.foo โโโ 1.foo/ โ serves 1.foo โโโ 2.foo/ โ serves 2.foo โโโ 3.foo/ โ serves 3.foo โ ... โโโ 9.foo/ โ serves 9.foo โโโ 123.foo/ โ serves 123.foo โโโ 1234567.foo/ โ serves 1234567.foo โโโ clankers.discount/ โโโ flawless.engineering/ โโโ drip.xxx/ โ already exists (drip-xxx-site โ renamed) โโโ patty.adult/ โโโ vilka.lol/ โ note: vilka.lol serves from Matilda, not vault โโโ (old flat files remain untouched for now)
Step 1: Change the nginx roots. Don't move any files. Just point each domain's root to its subfolder. Create the empty subfolders. Everything breaks (404s everywhere). That's expected โ it tells us exactly which domain was serving which files.
Step 2: See what breaks. The domain monitor at 0.foo will immediately show which domains go from 200 to 404. The ones that break are the ones that had content. The ones that stay 403 were already empty.
Step 3: Move files to their new homes. This is the part that requires decisions โ which files belong to which domain. That's a separate step, done file-by-file with Daniel's input.
Domains with actual content (served from /mnt/public/):
Domains with NO content (empty single-digit .foo + counting sequence):
Create a subfolder for every active domain:
mkdir -p /mnt/public/{0,1,2,3,4,5,6,7,8,9}.foo
mkdir -p /mnt/public/{123,1234,12345,123456,1234567,12345678,123456789}.foo
mkdir -p /mnt/public/clankers.discount
mkdir -p /mnt/public/flawless.engineering
mkdir -p /mnt/public/drip.xxx
mkdir -p /mnt/public/patty.adult
mkdir -p /mnt/public/if-anyone-builds-it-everyone-dies.{help,rip}
Just creates empty directories. Changes nothing.
Change every domain's root directive from /mnt/public to /mnt/public/{domain}.
Example: 1.foo goes from root /mnt/public; to root /mnt/public/1.foo;
This is a sed operation on domains.conf โ or more safely, a rewrite of the file from a template.
Backup first: cp domains.conf domains.conf.bak-pre-isolation
Why: This changes the serving root for every domain simultaneously. If the nginx config is wrong, everything goes down.
What happens: Show the diff of the new config vs the old one. Daniel reviews.
How to continue: Daniel says "looks right, reload."
nginx -t && systemctl reload nginx
At this point, most domains return 403 (empty folder, no index). 1.foo returns 404 for everything because its files are still in the parent directory. This is expected and correct โ it's the diagnostic step.
Move files that clearly belong to specific domains:
# 0.foo โ the domain monitor mv domain-status.html 0.foo/ # 123.foo โ family front door mv 123.foo.html 123.foo/index.html # 12345.foo โ Charlie's thing mv 12345.foo.html 12345.foo/index.html # clankers.discount โ fleet dashboard mv clankers.html clankers.discount/index.html mv clankers-backups/ clankers.discount/clankers-backups/ # flawless.engineering โ case studies mv flawless-engineering.html flawless.engineering/index.html mv flawless.html flawless.engineering/ (if different) # patty.adult mv patty-adult*.html patty.adult/ (rename main one to index.html) # if-anyone-builds-it-everyone-dies.* mv dies-help.html if-anyone-builds-it-everyone-dies.help/index.html mv dies-rip.html if-anyone-builds-it-everyone-dies.rip/index.html # drip.xxx โ already has its folder, just rename mv drip-xxx-site drip.xxx (or symlink)
Everything else โ the entire document library โ goes to /mnt/public/1.foo/. This is the main vault. All format specs, plans, reports, decks, fucks, PDFs, text files. 1.foo is the system domain.
The question is: do we move the files, or symlink them? Moving is cleaner. Symlinking preserves the old paths as a safety net.
Why: After moving files, every domain needs to be checked. The monitor at 0.foo will show the status, but we should also spot-check key URLs manually.
What to verify:
1.foo/deck โ still serves the deck format spec?1.foo/plan โ still serves the plan format spec?clankers.discount โ still shows the dashboard?flawless.engineering โ still shows the case studies?0.foo โ still shows the domain monitor?How to continue: All key URLs verified working.
Scripts that write to /mnt/public/ need to be updated to write to the correct subfolder:
domain-monitor.py โ currently writes to /mnt/public/domain-status.html โ change to /mnt/public/0.foo/domain-status.htmlfleet-monitor.py โ currently writes to /mnt/public/clankers.html โ change to /mnt/public/clankers.discount/index.html (and update backup path)/mnt/public/1.foo/1.foo/plan and 3.foo/plan can be different documents.drip.xxx/) without exposing the whole library.index.html landing page.Every external link to 1.foo/something will break if something.html isn't in /mnt/public/1.foo/. This includes links shared in group chat, in documents, in MEMORY.md, etc. Mitigation: move all document files to 1.foo/ before reloading nginx. Or: keep the flat directory as a fallback with try_files.
The upload endpoint at 1.foo/upload writes to /mnt/public/. After isolation, uploads would go to /mnt/public/1.foo/. Need to update the upload script's target directory.
The fleet monitor writes backups to /mnt/public/clankers-backups/. Links in the dashboard point there. Need to update both the monitor script and the backup path to live inside clankers.discount/.