I Wiped Every Docker Volume: The AI Warned Me, and I Deleted It Anyway
After deleting Docker.raw and losing every local postgres, I built shared infrastructure instead of trying to recover
The dev environments for three projects all run on Docker on a single Mac mini. Docker wouldn’t start at all, so I deleted the bloated Docker.raw, and I did it after being told plainly that the volumes would go with it. I figured it was only local dev data, so it would be fine.
What I set out to do
Yesterday Docker wouldn’t start at all on the Mac mini. The daemon didn’t respond, and restarting didn’t change anything. The dev environments for all three projects live on Docker, so I couldn’t do anything.
Looking at the disk, Docker.raw had ballooned. It’s the virtual disk image file Docker Desktop uses.
How I asked
I asked the AI. If I delete this, do the volumes go with it?
The answer was “yes, they’re deleted.” A clear answer. And I deleted it.
Reading the log again now, the AI said nothing wrong. Docker.raw is the entire filesystem including the volumes, and deleting it erases everything inside. I heard that answer and still approved with “yes, delete it.” Getting Docker back up was urgent, and I figured the local DB data was only for development anyway, so it would be fine.
Where it broke
Local postgres was wiped out.
Here’s where the “it’s only dev data” judgment was wrong. It’s not that dev data is unneeded; it’s that recreating it takes time. The backfilled disclosure data, the test accounts I’d entered by hand, the accumulated state of schema migrations: three projects’ worth.
Worse, I deleted it without knowing why it had grown that big. I erased the symptom without looking at the cause, so the same thing can happen again.
How I fixed it
I gave up on recovery. Instead, I changed the structure.
“OK, bring Docker back up now.”
The shared local infrastructure was not something I built then. It had been standing for ten days already. The disclosure-summary service moved onto it the same day it went up, and the legislative-activity tracker had moved over the day before the incident. The migration was in progress; the rest were still running their own postgres.
The incident finished that migration. I stopped running a separate postgres per project, and settled on one postgres that the three projects share, split by schema. Splitting by schema rather than by database was to match the shape of production, which runs on Supabase.
Why this is better.
- Fewer containers. Fewer volumes too. Fewer things to manage means less surface area for accidents
- Where each piece of data lives is gathered in one place. The most frustrating part of this incident was digging through three projects to figure out “what was lost”
- Ports and volume names that had been different in every project got cleaned up along the way
Without this incident, that migration would have dragged on much longer. The reason to move had been there for a while; it just was not urgent.
Lessons
- Even though the AI answered “they’ll be deleted,” I’m the one who deleted them. It told me the risk precisely, and I skipped past it because I was in a hurry. Whether the answer was right and whether the decision was right are different questions.
- Be careful with the judgment “it’s only dev data anyway.” It’s not that you can do without it; it’s that recreating it takes time. Estimate that time before deciding.
- Erase the symptom without looking at the cause and it will recur. I still don’t know why
Docker.rawgrew. - After an incident, changing the structure is sometimes better than recovering. Spending the time you’d use on restoring on preventing recurrence instead leaves you with more.
- An incident does not hand you a structure you didn’t have. It just makes you finish the move you postponed. The shared infrastructure had been there for ten days and I was halfway through moving onto it.
- Before a destructive operation, the habit of asking “what else gets deleted with this?” before running it is ultimately the cheapest thing. This time I asked and skipped past it anyway.