Graceful deploys
This page is for managers who approve changes to the live site and for the developer or operator who ships them. It explains what can go wrong during a deploy, how Exponential's deploy tools avoid dropped requests and stale pages, and the rules a business should agree on. The technical guide is Deploying, ship a PHP change with one command.
Contents
- What goes wrong in a careless deploy
- Graceful reload: no dropped requests
- The one-command deploy
- Why the order of the steps matters
- Small changes need less
- When a deploy needs a maintenance window
- Rules for the business
- Checklist
What goes wrong in a careless deploy
- Dropped requests: a server restarted the hard way refuses connections for a moment, and a customer in the middle of checkout gets an error.
- Old code still running: PHP-FPM and Velocity keep classes in memory. "Never run only
exp:cache clear --alland then forget the web server: FPM and Velocity keep the old classes in memory until they are reloaded" (Deploying). - Stale pages cached again: if the page caches are cleared before the server runs the new code, a page rendered by the old code in between is stored again and served as if the change had not worked (Operating a site).
- A slow first visitor: after a cache clear, the first visitor pays for the render.
Graceful reload: no dropped requests
On Exponential Velocity, graceful "re-executes the server without releasing the listening socket, so a deploy does
not drop requests" (README, "Using it"):
php bin/php/console exp:velocity graceful --allow-root-userWhat each engine does on graceful, from Velocity engines:
| Engine | graceful |
|---|---|
| Qbix | Re-exec, socket kept |
| FrankenPHP | Configuration reload, no dropped connection |
| PHP's built-in server | Restart (development only) |
When several Qbix instances share one port, graceful "reloads them one at a time, so the port keeps answering"
(Velocity engines). From engine
0.0.4.50 a stop also drains HTTP/2 connections gracefully (same page).
On Apache or Nginx with PHP-FPM, a graceful reload of the PHP-FPM service plays the same role; see Deploying, after every PHP change.
The one-command deploy
For a change to PHP code, an operator or a settings file, one command runs every step in the right order (Deploying):
php bin/php/console exp:velocity deploy --dry-run --allow-root-user # what it would do, nothing else
php bin/php/console exp:velocity deploy --allow-root-user # the usual case
php bin/php/console exp:velocity deploy --kernel --allow-root-user # a kernel class was added or renamedWhat a business should know about it:
- The dry run prints every step without changing anything. Ask for it to be part of every change request.
- A real run prints PASS, FAIL or SKIP and the time of each step, and stops at the first failure with exit status 1. A failed deploy does not carry on half done.
- The last step requests warm-up addresses (
[DeploySettings] WarmUpURL[]) in the background, "so the first visitor finds the caches built". - Options cover sites without Velocity (
--no-velocity, Apache only) and sites without PHP-FPM (--no-fpm). - A deploy whose caller is killed between stop and start finishes on its own, so the server is not left down (Velocity engines).
Why the order of the steps matters
"The order matters: the caches that hold finished pages are cleared last, after PHP-FPM and Velocity run the new code, so a page rendered by old code is never cached again" (Deploying). The deploy also avoids a needless PHP-FPM reload when OPcache picks up the new files by itself, because "a reload stalls every pool of that PHP version until its longest request ends" (same page).
Small changes need less
Not every change needs a full deploy (same page):
| Change | What it needs |
|---|---|
| A template or a stylesheet | Clear the template cache and Velocity's response cache; no restart |
| A settings file, a PHP class or an operator | exp:velocity deploy |
| A new or renamed kernel class | exp:velocity deploy --kernel |
| Content | No deploy: publishing clears the cached views of the item, its parents and related objects (View cache and cache blocks) |
When a deploy needs a maintenance window
exp:velocity deploy "does not switch maintenance on or off". For a deploy that changes the database or many files at
once, open a maintenance window first and close it after the smoke test
(Maintenance mode guide). See
Maintenance mode and planned work.
Rules for the business
Agree these with your team or partner, and write them down:
- Changes are tested first on a copy of the site, never first on the live one.
- Every change has a dry run and a named person who approves it.
- No deploys right before a peak (a sale, a newsletter send, a campaign launch) or at the end of the week.
- Every change can be undone: the previous version of the code is in Git, and a backup exists when the database changes (Backups that restore).
- Every deploy is checked: front page, a deep page, the administration,
var/log/error.log. - Every deploy is recorded: the audit trail records deploys in its
systemchannel (Audit trail for operations); add a line to your own change log too.
Checklist
- To do: The change was tested on a copy of the site.
- To do:
exp:velocity deploy --dry-runwas read and approved. - To do: A maintenance window is open if the database or many files change.
- To do: The deploy ended with every step PASS or SKIP.
- To do: Front page, deep page, administration and error log were checked afterwards.
- To do: The way back is known and a backup exists.
Related pages
- Velocity for businesses
- Upgrades without surprises
- Deploying changes (hosting)
- Free documentation: this page is free to copy, translate and improve under the GNU FDL 1.3.
Become an Exponential Partner
Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.