Hope is not
a deployment strategy
A client once described their deploy process to us in one sentence: open FileZilla, drag the changed file onto the server, hit refresh, and hope. That was the entire test plan. The change counted as shipped the moment the upload bar filled, with no record of what moved and no way back if it broke. WordPress CI/CD exists to retire that ritual and put machines in charge of checking code before customers ever meet it.
We inherit sites like this every month. The deploy history is one developer's memory, and that developer resigned last spring. Ask which plugin versions run in production and the honest answer is a guess. Every change becomes a small gamble, because nothing on the server can explain how it got that way or what depends on it.
The fix costs less than expected. Code lives in Git, every push triggers a test run, and a single command ships the result to production the same way each time. Two developers sharing a codebase is reason enough to bother. We treat this as the baseline for professional WordPress development rather than an add-on you have to request.
Releases in an ordinary week
From git push to live, tested code
Downtime visitors see per release
To bring the previous version back
The anatomy of a WordPress CI/CD pipeline
Git as the foundation
Composer-based WordPress
Automated testing
Staging that mirrors production
Blue-green deploys
Monitoring and alerts
Zero downtime
is plumbing, not magic
The mechanism behind it is old and well understood: atomic deploys. Each release gets built to completion in its own directory on the server, with Composer packages installed and assets compiled, while the live version keeps answering traffic one folder over. No file is ever overwritten in place, so visitors never meet a maintenance screen.
Then the release has to prove itself. Health checks confirm that the application responds, that it can reach the database, and that the pages customers actually visit render correctly. Only once every check reports green does a symlink move, and from that instant all traffic flows to the new build without a single dropped request. Because the cutover takes milliseconds, shipping at noon on a Tuesday in the middle of a campaign is no braver than shipping at three on a Sunday morning.
When a release does fail, the recovery is equally quiet. Point the symlink back at the previous build and the site is exactly where it stood, within minutes, with no backup restore and no apology email to draft. Visitors only ever saw a website that worked. The whole arrangement is written up in our case study on zero-downtime deploys in practice.
The same deploy, two ways
When is this overkill?
For some sites, frankly, it is.
A brochure site on a standard theme with a handful of proven plugins lives happily on wp-admin plus a maintenance agreement where somebody competent tests each update before it goes out. Wiring a full pipeline into that is buying a snowplough for a driveway in Spain. We say so. Loudly, if needed.
Revenue rewrites the calculation. A webshop taking orders around the clock cannot use production as its test environment, and neither can anything connected to Vipps or BankID, nor a codebase where several developers commit in the same week. From there on, each manual deploy carries a price tag. You learn the amount only after it detonates.
Our rule of thumb stays simple. When an hour of downtime costs more than NOK 10,000, or the site carries custom code meant to survive past its second birthday, the pipeline starts paying for itself. You build it once. The first broken release it stops usually settles the entire invoice.