One machine, everything: what I would do differently, and what's next
Seven months, 166 projects and 253 recorded mistakes on a single home server: what it gave me, what it cost, and the habits I would start on day one
Today, 5 November 2026, my lab’s written record holds 166 projects, 2,721 tasks, 2,701 observations, 61 runbooks and 253 mistakes. The first entry is dated 2 April 2026. Every one of them happened on the same machine: one workstation, in one apartment in Iași, running a Kubernetes cluster, an offline research library of about 120,000 works, honeypots that turn attacks into public threat intelligence, a mail server, monitoring, and local language models on a single GPU.
Two hundred and fifty-three mistakes in seven months is a little more than one a day. It is also a measure of attention: a mistake only gets an entry when someone notices it, understands it and writes down what to change.
This is the last post in a series about turning points: the moments that changed how I build and why. It is the one where I look back at all of it and answer two questions people ask me. What would you do differently? And what comes next?
Contents · 11 sections
In one minute #
- One machine gave me sovereignty, speed and a lab I understand end to end. It also made every mistake a whole-lab mistake.
- If I started again I would, from the first day: put everything in Git, write everything down, test restores instead of backups, give every service and agent the least access it needs, use names instead of addresses, and ask of every safety control whether it actually changes anything.
- I would keep the single machine, the written record, local models and the open way of working with AI.
- Next: an agent that works through my backlog while I watch, more of the library and OSINT shelf with the same provenance, and this blog.
- The honest weakness is the same as the strength: it is all on one machine, run by one person.
The before: a workstation that kept saying yes #
The lab did not start as a plan. By the time my written record begins, the workstation already ran a media server, local chat models, a Git server, honeypots, a library with its own search engine, and an AI agent that could read it. I cannot reconstruct the exact order in which they arrived, and that is part of the story: each one was a small “I could run that here”, and nobody was writing it down.
Together they became a cluster of around 150 pods. I once wrote a homepage counter for the number of pods, and within a single hour it read 141, 159 and 154. Any number I typed into my own website was wrong before I had finished deploying it, which is how I ended up writing live numbers on a static site with cron-generated JSON.
For a long time the only documentation was my memory. The written record began on 2 April 2026. Its Git history only begins in July. Before that, if I did not remember how something worked, nobody did.
What one machine gave me #
I want to start with the good, because it is real.
Sovereignty. My books, my models, my data and my mistakes live on hardware I own. When I ask my library a question, the search and the model both run on my own hardware. When an attacker hits my honeypot, the evidence is mine to analyse and to share, as in every attack here makes others safer.
Understanding. On one machine, there is nowhere for a problem to hide that I cannot eventually reach. Every incident on this blog ends with me understanding the mechanism, because the whole stack, from the disk encryption to the language model, is mine to read.
Speed of learning. A lab where everything runs in one place fails in interesting ways, often. Each failure became a lesson in the record, and the record became this blog.
What one machine cost me #
The same property, read the other way, is a list of single points of failure.
At 00:31 on 18 August a power cut of about 20 seconds turned into an outage of all night: the machine came back and sat at a disk-encryption prompt for 8 hours (a 20-second power cut, an 8-hour outage). That day’s reboot left 37 failed jobs and a wall of alerts. On 25 August one docker rm -f in a shell pipeline took the whole cluster down for about 20 minutes (one docker rm -f took down my whole k3s cluster). One October morning my GPU driver deadlocked with 33.9 of 34.2 GB of video memory in use, because a music player asked for a little more.
And on 3 October, a test deleted my home folder in about ten seconds (the test that deleted my home folder). On a machine where the home folder is also where half the automation lives, that is not a personal loss. It is an infrastructure incident.
I knew all of this in theory. The record is what made it concrete: a date, a duration and a cause for each one.
What I would do differently #
This is not a list of regrets. Each item is a lesson I already paid for, written down at the time with a root cause and a prevention. If I started again tomorrow, I would do these on day one.
1. Git and a written record, before the first service #
Four backup scripts, a small web app and a local certificate authority lived only in my home folder until the day it was deleted. They had to be rebuilt from their own output and, in one case, from the memory of a running process. Today every change is committed, pushed and recorded. Since October, an AI session working on my machine is stopped at the end of a turn if it leaves edits uncommitted. I would start that way. The record that grew out of this habit is described in a shared memory for me and my AI agents.
2. Restore tests, not backup checks #
On 7 July I found that 13 of 17 databases on my main PostgreSQL had never been backed up, while the job reported OK every night (backups that lie). Later, my cluster backup turned out to be saving a RAM disk instead of the database (Velero said Completed). My first real restore test reported 0 tables and 0 errors (my first restore test). Existence is not a backup. Only a restore you have tested is.
3. Least privilege from the start, for me and for every agent #
The home folder wipe did exactly as much damage as my permissions allowed. Data folders writable by my group lost their databases. Folders owned by their own service survived. My local AI agent now runs as its own user, in a sandbox, behind a permission gate (read, write, critical). It should have started there. So should every data folder.
4. Names, never addresses #
Internal addresses move. A container bridge changes on reboot, a cluster service gets a new IP when it is recreated. On one reboot at the end of October, a moved bridge address broke two network policies that had pinned the old one. Cluster DNS names do not move. I would never hard-code an internal IP again, and I would not treat “it has no public DNS record” as a wall either: 89 internal hostnames were one HTTP header away from the internet until I split my edge.
5. One secret, one home #
When I finally counted, one database password lived in 13 places, and one chat-bot token in about 40 (one password in 13 places, one notification relay instead of 40 copies of a token). Rotating either meant a treasure hunt. A single vault and a relay from the start would have saved weeks.
6. Ask every control whether it changes anything #
This is the lesson I keep relearning, so it gets its own section below.
7. Treat every AI output as a claim #
My AI assistants and my local agent have told me that code was unused when it was imported, that a model was broken in four places when only one was live, and once, that a check had passed fourteen hours before the check could even run. None of that was malice. It was confident text. I would build the habit from the first day: a claim from a model is a hypothesis until a tool output, a test or a clock confirms it.
The technical heart: three questions for every safety control #
Most of my worst incidents were not failures of something I lacked. They were failures of something I had, that looked fine.
A backup job that reported OK and saved nothing. An alert threshold set above the highest value its metric ever reached. A runtime security sensor that restarted 222 times in four weeks while the dashboard stayed mostly green (Falco on Linux 7.0). A language model that answered every request with question marks for 13 hours while its health check said it was fine (13 hours of question marks). A single sign-on policy that required two-factor login for three services that never passed through it.
One of my own recorded lessons says it best: verifying that a control was accepted is not verifying that it changes behaviour. So I now ask three questions of anything that is supposed to protect me.
- Does it exist? The config is applied, the job is scheduled, the policy is loaded. This is where most checks stop.
- Does it change behaviour? Feed it a case it must catch, and see it catch it. A restore. A request that must be refused. A value above the threshold.
- Would I know if it stopped? An alert on its age, its silence or its success rate, not only on its errors.
The third question is the cheapest to answer. For backups, it is one alert rule:
# alert when the newest successful backup of any set is older than its schedule allows
- alert: BackupStale
expr: time() - <backup>_last_success_timestamp_seconds > <max_age_seconds>
for: 30m
labels: {severity: warning}
annotations:
summary: "Backup set {{ $labels.set }} has not succeeded recently"
Every one of my backup sets has a rule like that now. A post-reboot script asks the second question for the whole lab after every restart (a post-reboot check script). And the canary that caught the question-mark model asks it of every loaded language model every 10 minutes, with a question whose answer it already knows.
What I would keep #
One machine. I know how that sounds after the previous sections. But the costs above are mostly costs of how I ran it, not of the machine itself. Hourly backups, a separate user for every agent, deliberate reboots and honest monitoring fixed more than a second machine would have. A second copy of the backups that does not live on the same NAS is still on my list. A second server is not.
The written record. It is the best thing I built, and it is not code. Every lesson in this series came out of it.
Local models. In late September I swapped an 8 GB card for a 32 GB one (swapping an 8 GB NVIDIA card for a 32 GB AMD GPU) and replaced a store of 49 models with one model router. Small local models cannot do everything. They can do a surprising amount, inside a structure that checks them.
Working with AI in the open. Everything I do with AI is in the record: the tasks, the mistakes, who made them, what we changed. I think that openness is part of staying honest about what these tools are. They are not colleagues with feelings. They are not oracles. They are very capable, very fast, and wrong often enough that the record matters.
What comes next #
The record also holds what is planned. Here is where the lab is going, in its own words more or less.
- An agent that works through my backlog while I watch. Small, scoped projects, one bounded step at a time, with a few reversible actions allowed on their own behind fixed rules and a second-opinion model. The rest proposed to me.
- More of the library and the OSINT shelf, with the same provenance. The research library already logs a fingerprint of every file in a signed, append-only log anchored in Bitcoin (a provenance ledger for a home library). The public-records shelf beside it is next to get the same treatment.
- Skills that other agents can use. The procedures my agent follows are plain Markdown playbooks. The plan is to make the same library available to other AI tools, so a lesson learned once is used everywhere.
- This blog. Every lesson in the record is a possible post. Sixty-one went out on the first day. There are a few thousand entries left.
The honest weakness #
It is all on one machine, and it is all run by one person.
The machine part I have made my peace with, for the reasons above. The person part is harder to engineer away. One engineer means one reviewer for every AI proposal, one person who knows where the bodies are buried, one pair of eyes at the post-reboot check. The record exists partly so that this is less true: so that what I know is written down, readable by me in a year, by an AI session tomorrow, and by anyone I choose to share it with.
It is not a solved problem. It is a mitigated one.
Questions people ask me #
Would you recommend running everything on one machine? #
For learning and for sovereignty, yes, with three conditions: tested backups to separate storage, least privilege for every service and agent, and a check you run after every reboot. Without those, one machine is one bad morning away from losing everything.
What was the most expensive mistake? #
The home folder wipe, in hours and in things that existed only once. But the most expensive kind of mistake was quieter: controls that looked fine and did nothing, sometimes for months. They cost nothing until the day they were needed.
How do you keep track of so many projects alone? #
A written record with a fixed shape: tasks with root cause and outcome, mistakes with lesson and prevention, runbooks, and observations. Every AI session reads it before starting and writes to it when it finishes. Without it, 166 projects would be impossible for one person.
What would you tell someone starting a home lab today? #
Commit everything, write everything down, and test one restore before you trust any backup. Then build whatever you find interesting. The mistakes will come anyway; make sure each one only happens once.
The point #
My tagline is “my space where chaos makes some sense”. Seven months of record later, I think that is the most accurate description of this lab I could write. It is not orderly. It is one machine doing far too many things, run by one person, with AI assistants that are brilliant and wrong in the same afternoon. The sense comes from writing it down: every failure with a date, a cause and the thing I changed.
I once wrote, in another context, “stay humble if you can”. Two hundred and fifty-three recorded mistakes make that easy. They also make the lab better, one lesson at a time, on the same machine, in the same apartment, every day.