Four WordPress sites ran on Gandi Simple Hosting M: carolegirard.fr, clementbodot.fr, pro.jngirard.com, and foozilla.net. I consolidated all four onto one self-managed OVH virtual private server (VPS), and the move looked like a single, irreversible step. The box was small by design, 4 vCores, 8 GB of memory, and 75 GB of storage on Ubuntu LTS in a Zurich datacenter, mirroring the hosting model it replaced. Three constraints shaped everything: one server, a downtime target under 15 minutes per site, and Gandi staying the source of truth until validation passed.
Consolidating meant one box shared by four tenants, each kept apart from the others . The point was never that managed hosting is bad; it was to own the one step that decides whether a migration is safe, the moment production changes hands. That control is what self-managed WordPress is about.
TL;DR
I ran the move as a blue-green DNS flip: a staging copy on the new box while the old host stayed live, production moved by an A-record flip, and the old host kept as a rollback I could revert at any point. They moved in risk order behind a soak buffer, and every install got a fresh core over migrated content.
Why “move” was the wrong model
The obvious answer was a cutover: take the sites down, copy them across, repoint DNS. The trouble is the shape of the loss, not its size. A cutover has no way back once DNS points at the new host, so every hour rides on one un-rehearsed moment. The unit to make safe is the point where production changes hands, and that point can be made to point back.
The decision: flip DNS, keep the old host live
I built a parallel staging copy on the VPS while Gandi stayed live, checked it through a local hosts file first, and moved production with the A-record flip. Gandi kept running until 48 hours of post-cutover validation passed, then stayed as rollback reserve for about 7 days; rollback is the A record reverted, with zero data loss. A single-downtime cutover carries no rollback and a real data-loss risk; keeping Gandi indefinitely means paying for two hosts.
A flip is not the only gate. Validating a web server’s configuration before reloading it is a discipline of its own : Apache will reload a broken configuration without complaint.
The order the sites moved in
I did not move the four sites together. Each moved on its own, in risk order, behind a soak buffer that was never skipped.
| Site | Risk | Soak buffer after the flip |
|---|---|---|
| foozilla.net | zero, the validation target | 24 hours |
| pro.jngirard.com | low | 48 hours |
| clementbodot.fr | medium | 48 hours |
| carolegirard.fr | high and revenue-critical, moved last | none, it moved last |
The buffers separate validating a procedure from assuming it. I rejected moving all four back to back because risk compounds: the revenue-critical site would ride on an unvalidated procedure. carolegirard.fr carries appointment bookings for a naturopathy practice, so it moves last. The scheduled plugin work a buffer surfaces has a mechanism of its own .
A fresh core over migrated content
Nothing stale traveled. I moved wp-content (themes, plugins, uploads, and mu-plugins), the full database dump, and only the custom root files: a .htaccess converted to Apache 2.x syntax where needed, robots.txt, and favicon.ico. The core itself never migrated: I deployed a fresh WordPress core on the VPS, kept the PHP 8.x and MySQL 8.x the host already ran, re-created the wp-config.php customizations by hand, and regenerated the salts locally rather than carrying Gandi’s across. I rejected copying the whole install with its core and salts: a stale core, and secrets that should not survive a move.
What broke, and what the buffers guard against
Nothing broke. All four records report the same result, and I will not dress that into a story it is not. 48 hours catches what the first 2 hours do not: a plugin job that fails silently, a cache that serves stale content until it warms, and email that drifts to spam. The cutover I rejected risked data loss with no way back; the buffers answer the same concern.
The outcome, and what it rests on
Production moves by DNS. One self-managed VPS carries the full Gandi workload, and the Gandi hosting dependency is retired. I state this at the runbook’s level: its own conditions and stated outcome, not a measured uptime. “Lost nothing” means exactly this: the rollback is an A-record revert with zero data loss, and it stayed available for 7 days. A promise like that rests on a restore you have actually tested, a discipline of its own .
The operator behind this stack, and its trade-offs, are on the about page. If this is the shape of your problem, let’s talk.