Agentic migration of my homelab

Hi everyone!

In today’s post, I want to walk you through how I handled the migration of my old “Homelab” to a “new” PC by leaning on Claude, Matt Pocock’s skills, and a set of custom agents. I’ll tell you what went well and what didn’t work at all (trying to figure out why), as there were several failures along the way that I’ll explain and show how I tackled them.

Spoiler: the migration was a success!

Starting point

My homelab was a Raspberry Pi 4B with 4GB of RAM, running Raspbian and a series of services as Docker containers (including Home Assistant, n8n, Node-RED, and other services I built to manage my home automation). For a while now, the service load had saturated my poor Pi’s RAM, leading to constant swapping.

The “new” homelab is an old PC of mine with 8GB of RAM (plenty to comfortably handle all services), a 9th gen i7 processor, and a 500GB SSD. It’s certainly not a powerhouse with top-tier performance, but it’s enough to handle the required load.

Migration goal

The overall goal was obviously to move everything from the Raspberry Pi to the new PC, paying close attention to these points:

Backup: Container and volume backups were managed by Backrest and rclone (to upload backups to the cloud). This setup had to be preserved.

Home automation downtime: downtime for my home automation had to be kept to a minimum, and all necessary precautions had to be taken to handle a possible rollback if something went wrong.

Docker: Every service on the Pi was managed with Docker and Docker Compose, a choice made to simplify any future PC change and to isolate services from the OS.

Proxmox: with this migration, I wanted to switch from Debian to Proxmox, mainly to move Home Assistant from a container to HAOS. However, I wasn’t sure if the PC could handle the load of Proxmox + HAOS + Debian (for the remaining containers). This point needed a deep dive.

Step 1 – Environment and tools setup

I’ve used Obsidian as a second brain for years, and for this project, I built a dedicated directory to centralize all markdown files, scratchpads, tickets, and materials produced during this migration. I did this within my Obsidian vault because that’s where I manage all my projects, and with sync active, I knew nothing would be lost.

Once the directory was ready, I created these agents under .claude/agents:

  • An agent specialized in Home Assistant (with the rules and configurations of my environment)
  • An agent specialized in Proxmox

Next, I created a CLAUDE.md file detailing the Raspberry Pi’s specs, the PC’s specs, my migration goals, and the agent skills to use.

Finally, for this migration, I used Matt Pocock’s skills, which are fantastic for bringing order to activities. If you’ve never seen them, I highly recommend checking them out—they’re incredibly useful and available on the AI Hero site. Once installed, run the /setup-matt-pocock command from the Claude CLI (or your preferred provider) to set up the general usage rules for these tools. At one point, it will ask where to save the tickets it creates; I chose to keep them locally in the .scratch directory.

This was my starting point.

Step 2 – OS choice

Would the PC handle Proxmox, or should I stick with Debian? To figure this out, I started with the /wayfinder command (using the Opus model), which is great for finding direction when you’re not sure where to go or which path to take.

This command led to an analysis that lasted several hours, involving various questions I had to answer (split across several sessions due to token limits). In short, the steps of this analysis session were:

  • Collection and analysis of current Raspberry Pi metrics (handled by sub-agents) to understand the load and resources used by current services.
  • Separation of Home Assistant container metrics from other services, handled by sub-agents.
  • Q&A on aspects such as backups, high availability, machine management, update management, etc.
  • Creation of a notes file where every discovery and decision was recorded. This was a fundamental point; without it, I would have burned through way more tokens in later phases because I would have had to re-analyze the data.
  • Management of post-migration tests.

At the end of this process, several tickets were generated with the decisions made, some deep-dive tickets (e.g., how to manage containers on Proxmox), and some correction tickets for anomalous situations (e.g., two services had a wrong backup policy that prevented them from starting).

Anyway, the verdict was that Proxmox with HAOS and Debian could run on the PC with 8GB of RAM and a 9th gen i5.

This was one of the first mistakes that cost me a lot of time.

In reality, the machine was NOT sized to handle Proxmox + HAOS + Debian. Why didn’t it warn me? Because of the data. I hadn’t given Claude the chance to make the decision based on real data (a condition in the rules and a lack of actual data), so it based its assumptions on web searches and estimates.

Personally, I wasn’t 100% convinced, but I decided to install Proxmox anyway, with the idea of actually testing the installation of HAOS and the containers and deciding later if the PC could handle it.

Step 3 – Proxmox and MCP server installation

I installed Proxmox on the machine and configured its MCP server: this move always aims to provide Claude with real, up-to-date data.

Step 4 – Fixing Raspberry anomalies

Before proceeding with the migration planning, I used the /grill-me-with-docs skill to do a deep analysis of the Raspberry Pi to:

  • Analyze each service looking for problems in the Docker logs.
  • Identify configuration anomalies (docker-compose or specific configs).
  • Verify that all backups were correct.
  • Verify that the backup strategy was correct for all services (using Backrest + rclone).
  • Clean up old logs without a retention policy.

One of the anomalies found was with Mealie, a recipe service my wife uses, where the Docker volume was backed up without exporting the database. At a backup level, no error was raised, but I would never have been able to perform a correct restore of the service just by copying the directory with the database files.

At the end of the session, I had several tickets, each focused on fixing a single problem. For each ticket, in a fresh session, I used the /implement <ticket> command to fix the issue.

Once all generated tickets were processed and closed, I was ready for a planning session on how to handle the migration.

Step 5 – Migration planning

Using the /grill-me-with-docs command, I started a session lasting a few hours to define the migration strategies.

I immediately requested a “gradual” migration, moving the least critical services to the new PC first, before moving to the home automation services.

Based on this, Claude started to “insist” on the need to split the home automation services from the non-home automation ones into two separate virtual machines (on Proxmox).

It’s curious how this also went against the available hardware; in fact, the proposal was: Proxmox + HAOS + 2 Debians—an unsustainable load, as if it had “forgotten” the machine’s specs.

Naturally, I politely rejected this split.

At the end of this session, I had several tickets in the .scratch directory and a very detailed migration roadmap.

Each service to be migrated corresponded to a ticket, plus others dedicated to side activities (environment preparation, backup verification, tests, etc.).

Step 6 – Migration

Premise: I wanted Claude to handle the entire migration, except for commands requiring sudo privileges, which I would run as needed. Claude obviously had SSH access to the machine via a dedicated user.

I processed the migration plan with deliberately small, atomic tickets, so I could handle them one by one.

The migration was split into two different moments: in the first phase, I migrated non-home automation services (about 10 applications, one at a time); in the second phase, I migrated all home automation services (Home Assistant, n8n, Node-RED, and other apps of mine) all at once. To achieve this, I had Claude prepare all services on the new machine (container images already downloaded, volumes ready, etc.), and during the migration, I only did one thing: backup the latest data on the Pi, move the backup to the new Homelab, shut down one side, start the other, and verify the operation (both by Claude and by me).

Strategy

Leaving aside the two-phase split, there were some common elements I’ll talk about now.

The context window was my biggest concern; I didn’t want to saturate it beyond 150/200k tokens (to avoid performance degradation and an increase in hallucinations), but at the same time, I wanted to maintain a single session, processing all tickets together.

The strategy I adopted was as follows:

  • Single context window, processing one ticket at a time with the /implement <ticket> command. Working one ticket at a time slowed me down, but it allowed me to keep the migration under control.
  • At the end of each task, the roadmap and a scratchpad file with migration notes (rules I added to the CLAUDE.md file) were updated.
  • Before starting a new ticket, I ran the /compact command to reduce the context and start as clean as possible, preserving a minimum context. By the end of the migration, the compacted context occupied about 25k tokens, plus 50k tokens added by default by Claude (its context, MCP server, etc.).
  • I always used Opus as the model, both during brainstorming and migration. In this regard, I noticed that during the operational phase, it was far more capable than Sonnet 5 at identifying problems and solving them, which is why I stuck with this model, despite the token consumption. The only time I used Sonnet was when post-migration tests were run via a dedicated sub-agent.

Challenges encountered

Now that we’ve seen the strategy, let’s focus on the challenges I hit.

Daily limits

I have a Claude PRO account, and this didn’t give me much “breathing room”; I often ran out of tokens and was forced to wait. The brainstorming session lasted 5-6 Claude windows, while the actual migration took about 4 days.

Tests

In the CLAUDE.md rules, there was an instruction that everything migrated must include a test plan to verify that everything was operational as before. I noticed that the test plan wasn’t always accurate and summary tests were performed (e.g., service reachability). I solved this by changing the rules in CLAUDE.md, adding that tests had to be managed by a dedicated sub-agent. I then created a dedicated agent with the rules it had to follow for test management (writing and execution), located in .claude/agents.

Step 7 – Post-migration checks

After completing the migration, I planned check windows at 2 hours, after one night, and after one week, after which I would declare the migration complete and shut down my beloved Pi. What to check had already been defined during the analysis phase; each check moment had a dedicated ticket with a list of the main things to monitor (mainly logs and various reports I would provide).

In this phase, no anomalies were found—everything was migrated correctly!

Conclusions

This migration taught me a lot on one hand, and confirmed some things I already knew on the other. I’ll summarize the most important points from my perspective:

Working “vibe” doesn’t work I’m a developer by trade, and I’ve never believed in “vibe coding,” and this migration confirmed it. In the development world, I’ve seen many projects created with this approach, but with enormous architectural or scalability problems: did they work? Yes, but they took their toll after an initial phase.

I had to govern many aspects of this project: discarding Proxmox, boycotting the double VM for home automation apps, improving test management. These are all examples of how maintaining control over the project and the direction the agents are taking remains fundamental (at least for me). If I had let myself be carried away (pure “vibe”), I probably would have migrated all services to a machine with Proxmox, finding myself with the same performance problems I was escaping.

The importance of structured work Using a ticketing system, the analysis and planning phase at the start, and Matt Pocock’s skills contributed significantly to the successful outcome of the migration. This applies to life and also to our agents.

Minimal context Keeping the context under 150/200k tokens significantly decreases hallucinations and the model’s loss of attention toward what we’re doing. To achieve this, it was fundamental to work with sub-agents (which have a context separate from the main one), break the work into small, atomic sub-tickets, and work heavily with the /compact command before tackling a ticket.

Notes files (scratchpad) and roadmap The presence of these two files in the project directory was fundamental. Having them allowed me to have a file always updated with the current situation and enabled me to start a new Claude instance from different tools without depending on a single chat with all the context.

I hope this article was useful to you, see you next time!

Share this article
Shareable URL
Prev Post

Up-to-date technical documentation for your agents

Read next

Claude 4.5

Claude Sonnet 4.5 has just been announced and released! In this article, I’ve compiled the key highlights…