Skip to content

Powered by Grav

Deploying your code — Cheat Sheet

Deploying your code — Cheat Sheet

Bringing your own Drupal is the normal way to run production here: you build the code in your own space with Composer or git, then hand the finished codebase to Ægir with one form. This page is the quick primer: where to build, how to register it, the one rule that keeps live sites safe, what to do on a security-release evening, and the in-place route with its warning. Everything here links to the full story.

The pieces in 30 seconds

  1. Build in ~/static/platforms/ — your code lives there, and BOA upgrades never overwrite anything under ~/static. ~/distro/ is BOA's own and gets rewritten, so keep nothing there. → Building your own platform
  2. Register it once — Platforms → Add platform, point Platform Path at the project folder, save; the queued Verify finds the real docroot for you. → Register it as a platform
  3. Frozen once live — never run composer update in a platform that has live sites; build a fresh one beside it. → Deploying your own code
  4. Sites move with Migrate — a test site first, then the rest; rolling back is migrating back. → Cloning & migrating
  5. Production runs on your own build — the Drupal 8+ platforms BOA provides are for demonstration and compatibility testing, not production. → Who covers which layer

Build your code in ~/static/platforms

From your oN.ftp shell, build a current Drupal with Composer (swap ^10 for ^11 for Drupal 11), with Drush in the build so you can run database updates later:

BASH
cd ~/static/platforms/
composer create-project drupal/recommended-project:^10 mysite
cd mysite
composer require drush/drush
composer install --no-interaction --optimize-autoloader

Existing code in git clones into the same place, followed by the same composer install. Composer runs on your command-line PHP (~/static/control/cli.info): Drupal 11 needs PHP 8.3 or newer, so check composer -V first.

Drupal 11 also needs a server on Percona 8.4: on an older database server a Drupal 11 site Install stops with that one reason. On a hosted plan, ask your host for a Percona 8.4 engine before you build.

→ Building your own platform · Drupal 11 needs Percona 8.4 · Choosing a PHP version

Register it: Add platform (if your plan allows)

In the control panel, go to Platforms → the Add platform tab. Set Platform Path to the project folder, for example /data/disk/o1/static/platforms/mysite (your instance name in place of o1), give it a Platform Name, and save. Ægir queues a Verify; a minute or two later the platform is ready, and Sites → Add site puts sites on it.

You don't add /web yourself: when there's no index.php at the top, Verify checks docroot/, html/ and web/, in that order. If the Add platform tab isn't there for you, it's a switch your host controls — ask them.

→ Register it as a platform · Adding your own platform

The frozen rule: build fresh, then Migrate

Once a platform has live sites, never run Composer inside it again: a composer update there can overwrite core/ and vendor/ underneath running sites. Newer code goes on a fresh platform beside the old one, built the same way as the first:

BASH
cd ~/static/platforms/
composer create-project drupal/recommended-project:^10 mysite-new

Register mysite-new, migrate a test site onto it, check it, then migrate the rest and retire the old platform. The old one stays exactly as it was, so a site that misbehaves simply migrates back. Read-only commands such as composer outdated drupal/* are safe to run anywhere.

→ Keeping the code up to date the safe way · the safe upgrade order

When a Drupal security release lands

Drupal publishes security releases on Wednesdays, between 16:00 and 22:00 UTC, and the mailing-list email goes out at the end of that window naming every affected project — act on that one. From the platform's app root (the folder with composer.json), two checks only read and need no unlock:

BASH
composer audit --locked       # every known advisory affecting the locked packages
composer outdated drupal/*    # every Drupal package with a newer release

(The audit counts only when composer.json declares the drupal.org packages repository, as any build with contributed modules does.) Then take the same-evening route: a fresh platform with the fixed release required explicitly, one test site migrated, then the rest:

BASH
composer require drupal/module_name:^1.8 --update-with-dependencies

A site still on a BOA-provided platform takes the same route for good: build your own copy of that distribution or core in ~/static and migrate onto it.

→ When a Drupal security release lands

In place — only if you accept extended downtime

Never use this method unless you are prepared for extended downtime. BOA keeps a live platform's code owned by the backend user; while ~/static/control/unlock.info exists, the nightly run hands your ~/static platform code to your shell user instead:

BASH
touch ~/static/control/unlock.info   # wait for the nightly run, then check with ls -l
rm ~/static/control/unlock.info      # as soon as the work is done

Back up the codebase yourself first (the Backup task never includes platform code), and prove the sites work once the caches have expired before any Verify: a platform Verify locks the code again at once, and a Verify on broken code keeps the sites down until the next nightly run.

→ In-place upgrades: unlocking your codebase

Private repositories

Your own clones use your own credentials. Fetches Ægir runs for you use your instance's key: register ~/static/o1.id_ed25519.pub (your instance name in place of o1) as a read-only deploy key. → Shell & Drush cheat sheet · Private repositories and the deploy key

The files most people touch

File or field What it does Default
~/static/platforms/ Where your own codebases live; BOA upgrades never overwrite ~/static Recommended layout; any path under ~/static works
Platform Path (Add platform) The folder Ægir registers; Verify finds the docroot itself The project folder
~/static/control/cli.info The PHP version Composer builds with (BOA default)
~/static/control/unlock.info Hands platform code to your shell user overnight, for in-place work only (absent — locked)

Five more control files belong to this topic, among them compass.info for the Sass/Compass and Node theme tools — each is documented in Deploying your own code and catalogued in the control-files reference.

If something's weird

  • Verify says it can't find Drupal, or the platform shows an unknown version → the build is broken or incomplete; re-run composer install, check index.php exists (at the top on Drupal 7, under web/ for a Composer layout), then verify again. The docroot note.
  • A Drupal 11 site Install stops at once, saying it needs MySQL 8 → the server runs Percona 5.7; nothing in your codebase was touched, so ask your host for Percona 8.4. Drupal 11 needs Percona 8.4.
  • After the migrate, a site still runs the old module version → a copy in sites/example.com/modules shadows the platform's; site-local code travels with the site, and no platform move updates it. Where your modules belong.

Going deeper

© 2026 BOA Documentation. All rights reserved.