Forty client sites on a ten-year-old bare-metal LAMP box. The decision matrix came down to three columns: containers we run, managed WordPress hosts, or pay down the debt in place.

The decision matrix

Managed hosting won on the only metric that matters at this scale: who gets paged. Thirty-eight sites fit a standard managed profile; two had cron jobs and custom Apache modules old enough to vote.

The migration weekend

Rsync, database dumps, DNS with one-hour TTLs dropped a week ahead. Thirty-eight sites moved in a weekend with a spreadsheet checklist and zero client tickets.

The two that fought back

One depended on a local Postfix relay nobody documented; one had hardcoded absolute paths in fifteen years of uploads. Both are now containers on a small VPS — the escape hatch, not the default.