
What remains, and we would rather you heard it from us than found it: enabling Encryption on an adopted site is still a manual step per site (the certificates then arrive through the proxy window on their own), per-client SSH sub-accounts are not part of the automated flow, so they get recreated by hand on the target, pre-3.x Ægir sources are refused outright, and the old panel URL goes dark once the proxy takes over: the sites travel, the panel’s address does not. If you run the road before we close those, tell us what you find.
Back to the blog »
And until DNS moves, every step of this has a drilled way back. One site: revert --site example.com --live, the original vhost comes back from its dotfile and the site is local again, as if nothing had happened. The whole estate: revert --all --live, then resume --live, which wakes the source automation up again exactly as it was found. One rule to respect, and the tools hold the first half of it for you: a reverted site is re-exported before any retry, its markers cleared the moment it comes back, and its target copy reset, which is your command to run. A site serving locally again is writing into a database its shipped dump no longer matches, and cutting over from a stale dump loses writes without a word. The revert chapter spells all of it out, target side included; the way back stays in your own hands, not in somebody’s support queue.
Stage one flips the source from Apache to Nginx, on the box itself, because everything later on the road speaks Nginx. This sounds scary and it is designed not to be: Nginx and PHP-FPM are installed without starting anything, Apache keeps port 80 the whole time, and before any handover the tool runs real PHP through the new pair on a spare port while Apache is still the one serving, so the replacement is proven before the old engine is ever switched off. Both stacks then stay installed until you sign off, which keeps the revert cheap, and in our drills the flip took about a minute and the way back even less (with the task queue daemon running; a cron-only box takes longer), encrypted estates included, certificates answering at every step. Why keep both engines in the car? Because a revert you would first have to install packages for is not really a revert any more, it is a rescue operation with a friendlier name.
Stage two is the migration itself: one dual-resident script placed on both boxes, and a chain of verbs which reads almost like the checklist it enforces: peer first, because a first-contact SSH burst is exactly what a firewall daemon reads as an attack, then check, pre-mig, create, export, transfer, import, proxy, cert-sync. There are two adoption routes, and you do not get to pick one by feeling: check decides from the discovery data, and if you ask for the whole-database route anyway it refuses by naming exactly what your estate fails, so the machine argues with reasons, never with silence. The default route adopts site by site, one bad site fails alone, its panel bookkeeping starts fresh on the other side, and composer-era platforms travel as the projects they are, so a Drupal 9 site arrives with its vendor directory and serves. The second route, for homogeneous Drupal 7 estates on current Ægir 3.x only, imports the whole hostmaster database and carries the panel history across.

Is there, somewhere in your care, a vanilla Ægir server everybody has quietly agreed to leave alone? Somebody who cared set it up years ago (on Apache, on a distro which was modern at the time), then the somebody moved on, the agency dissolved or the contract ended, and the box just kept serving its Drupal sites, because that is what Ægir boxes do. Or did you leave such a box behind yourself, years ago, when the industry decided self-hosting was over, and you wonder now and then what it would take to bring those sites back under your own roof? We have a soft spot for these machines, and a concrete reason for it: Omega8.cc itself began on vanilla Ægir back in 2009, so when we say the aegir2boa toolset welcomes classic estates home, we mean the word home quite literally.
Stage three is not a tool at all, and deliberately so. Lower your TTLs a full old-TTL period ahead, repoint DNS at your own pace (the proxy keeps every site serving either way), move the mail records with the care they deserve, and only when the old box serves nothing but memories do you switch it off; the decommission checklist is seven short items, and the power button is not even the last of them. No verb exists for this stage because the machine cannot know when you are ready; that call stays yours.
The toolset is free and open source, like the rest of BOA, and no BOA box ever fetches it by itself: you download the three scripts straight from files.boa.io each time, never from a copy already lying on some box, because they never self-update, and the source box needs no BOA, no account and no credentials to receive them. Then start with stage zero and let it tell you the truth about your machine. Two doors into the runbook: the operator guide if you are the one typing, the self-hosting page if you are still deciding, and if you read nothing else there, read the revert chapter, the one place where a migration guide explains how to undo itself before it explains how to run. And what does an adopted estate actually get once it lands, the nightly machinery, the one-task sandboxes, the upgrades everyone kept calling impossible? If your estate is one of those quiet boxes nobody has logged into for years: it has done its job well, and the way home does not ask it to be brave, only to keep serving a little longer while its sites move across, and nobody hurries that, us least of all. We came out of that same door ourselves, welcome home!
The whole road was proven on throwaway boxes, on the published tool bytes you would download yourself, and not just once. A fresh estate carrying real Let’s Encrypt sites and a Drupal 9 platform built with composer went first, and that run alone paid for itself in defects found, an HTTPS flip which had never been exercised, composer platforms whose vendor directory did not travel, all fixed and re-drilled before we recommended any of it. A mixed Drupal 6 and 7 estate followed, adopted end to end, proxy window and every revert leg included, and because so many of the vanilla boxes out there run Ubuntu, an Ubuntu source with the distro’s own MySQL 8.0 went through the lot as well, the flip and its way back included, and landed succesfully in a Percona 8.4 target. Then the whole thing once more as a matrix, both flavours of source into both database generations we ship, which is how we learned that a Drupal 6 site on a Percona 8.4 target needs the server to still speak the old password handshake (PHP 5.6 hangs up on the modern greeting before it even says hello), so the import now pins those users and refuses, loudly, when the server will not play, and BOA itself sets the server side; what has actually been drilled is written down there, run by run.
The obvious instinct is to upgrade such a box in place, and it is the wrong instinct. A vanilla box converted to BOA where it stands has no cheap way back, and a machine which nobody fully remembers any more is the last machine you want to gamble on. So the safe shape is different: migrate remotely, to a separate BOA box (your own or ours), and demote the old server to a small HTTP(S) proxy which keeps answering on the old IP while DNS catches up, because then the way back, for any single site, is nothing more dramatic than moving one file.
This is what the report looks like on a mixed estate, two Drupal 6, four Drupal 7 and one Drupal 9 site on one throwaway test box, WARNs left in; click on the picture for the full version.
The short version, for anyone who will read the runbook later and wants to know now whether it is worth an evening: three scripts, the first only reads your box and grades it, the second swaps Apache for Nginx in place after proving the replacement on a spare port, and the third carries the sites one by one to a separate BOA server while the old box stays on its IP as a small proxy, so nothing you run is a leap, and everything before DNS moves has a way back exactly one file wide. Every command is a rehearsal until you say otherwise, and the rehearsal has to come back clean before the real thing is even accepted. The whole road is drilled and written up step by step in the aegir2boa operator guide, which tells you what to type; the interesting part is why the road bends where it bends.
That dry-run habit is the decision the rest of the road hangs on. --live is not a habit you can develop: it is accepted only when the dry form of that same verb, on the same scope, on the same box, came back clean, and it uses that clean run up on entry, so one rehearsal buys you exactly one performance, and a live run which fails sends you back to a fresh rehearsal against the box as it now is. The second standing principle is even simpler, nothing serving is ever cut before its replacement has proven itself, so every failure before a handover is an abort nobody’s visitors notice.
What travels, and from where, turned out to be the interesting half. A Drupal 6 site, and there are more of those still serving than anyone likes to admit, goes the per-site way, registered under the install profile it was born with and pinned to the target’s PHP 5.6 pool, so the oldest sites in the building arrive as themselves. The source may be Debian or Ubuntu, both drilled end to end: the tools branch on what they find on the box, the init system, the Apache layout, the database flavour, rather than on a distribution’s name, and a MySQL 8.0 source is told by check, before anything moves, that it needs a current-generation target.
Two populations we have not met yet: a target without a PHP 5.6 pool, where the refusal you would get exists in code but not yet in our logs, and the very oldest servers, the upstart-era Ubuntu and Apache 2.2 generation, which the tools recognise by feature detection that has never run against a real box of that age, because no cloud image of one exists any more, so there you read every dry run twice.
Along the way each site is paused behind a 503 stub, dumped with its own database credentials (the tool never asks for root database access on the source), shipped to the target, registered there and probed against its pre-migration baseline. A 200 alone does not count as an answer there: the tool first asks the target what it says to a hostname which cannot exist and turns down any site whose reply is that same page, and only then is the site cut over, one file swap at a time. Our favourite detail stopped being small the day it was drilled: the proxy forwards ACME challenges, so the target mints and renews real Let’s Encrypt certificates for domains still pointing at the old box in DNS, and cert-sync copies the fresh certificates back out to the proxy, weekly if you let it install its own little cron; the one manual step in all this, enabling Encryption per site on the target, has a chapter of its own in the guide.
The road has three stages, plus a ‘stage zero’ which costs you nothing. aegir2boa-preflight is a read-only discovery tool: it installs nothing and changes no service, it writes its findings under /tmp with two verdicts on top, one each for stage one and stage two, graded PASS, WARN or FAIL. And do read the WARN correctly: it names caveats to resolve or consciously accept, nothing worse, and a typical healthy box shows one or two. Some boxes are refused outright with named reasons (a BOA box, a box with no Ægir on it, an Ægir older than 3.x), and for these FAIL means stop.






