security

Patch Day Without Panic: A Drupal Security Update Workflow

composerdrupalmaintenancesecurityupdates
Gerald VillorenteOctober 30, 20267 min read
Patch Day Without Panic: A Drupal Security Update Workflow

Every Drupal security update brings the same dilemma: patch fast and risk breaking the site, or wait and risk getting hacked. This guide gives you a calm, repeatable workflow that removes the dilemma: back up, rehearse on staging, update with Composer, test, deploy, and know exactly how to roll back. Follow it monthly and patch day becomes routine instead of terrifying.

If the recent PHP2Shell emergency rattled you, start with what happened and why updating matters. This post is the other half: the hands-on process that turns "update immediately" from a scary order into a checklist you can run before lunch.

Here is the workflow:

  1. - Understand why patching usually lags

  2. - Prepare: backup, staging, and reading the advisory

  3. - Run the update with Composer and Drush

  4. - Smoke-test before anyone else notices

  5. - Roll back calmly when something breaks

  6. - Make it a monthly habit with a runbook

  7. - What the habit earns you

Why Drupal Security Updates Get Delayed

Almost nobody delays patching out of laziness. They delay because last time something broke: a contrib module conflicted, a template behaved oddly, or the site went white-screen for twenty minutes while visitors watched. Every painful patch teaches the team that updating is dangerous, so updates slide from monthly to eventually to never. Then an advisory like PHP2Shell lands and the site is three versions behind with no safe path forward.

Notice the trap. Skipping updates does not avoid risk, it concentrates it. A site that patches monthly absorbs small, survivable changes. A site that patches yearly absorbs a year of changes at once, usually under emergency pressure. The workflow below exists to make the small, frequent path boring. Boring is the goal. Exciting patch days are the ones that end badly.

Prepare First: Backup, Staging, Advisory

Preparation is what separates a calm update from a gamble. Do these three things before touching production, every time, no exceptions.

First, back up what you cannot rebuild. That means the database and any user-uploaded files. Code is in version control, so it can be re-created, but the database cannot. Verify the backup exists and is recent before continuing. A backup you have not checked is a hope, not a backup.

Second, rehearse on staging. Your staging environment should mirror production: same PHP version, same modules, a recent copy of the database. Run the entire update there first. If staging does not mirror production closely enough to trust, that gap is itself the first thing to fix, because it makes every future patch a coin toss.

Third, read the security advisory. Drupal advisories tell you which versions are affected, how critical the issue is, and whether it is already being exploited. A critical core issue with exploits in the wild means patch today. A moderately critical contrib issue on a module you barely use can wait for your normal window. The advisory sets the urgency, and urgency sets the schedule. Do not let anyone rush you past staging because the advisory sounds scary. Urgency changes when you patch, never whether you prepare.

Run the Update With Composer and Drush

With preparation done, the update itself is mechanical. Run it on staging first, verify, then repeat the exact same steps on production.

Start with Composer, which manages Drupal core and contrib modules. This updates core and lets dependencies resolve together:

composer update drupal/core "drupal/core-*" --with-all-dependencies

Review what Composer plans to change before saying yes, especially major version jumps and anything marked abandoned. Then apply database updates and rebuild caches with Drush:

drush updatedb -y && drush cache:rebuild

Export any configuration changes the update produced so they are captured in version control rather than living only in the database. If your workflow exports config on deploy, confirm the export is clean and committed.

Do the steps in the same order every time: Composer, database updates, cache rebuild, config export. Same order means the process is debuggable from memory, and anyone on the team can pick it up mid-way. If a step fails, stop. Do not stack a second change on top of a failed first one. Read the error, fix it on staging, and only then continue.

Smoke-Test Before Anyone Else Notices

An update is not done when the commands finish. It is done when you have confirmed the site still works for visitors. Keep a short smoke-test list and run it after every patch, on staging and again on production.

  • Load the homepage, a content page, and the login page. Look at them, do not just check status codes. A 200 response with a broken layout still ruins mornings.

  • Log in as an editor and save a test node. Editing exercises the database writes and permissions paths that break most often.

  • Submit the most important form on the site: contact, checkout, donation, application. Whichever one the business cannot live without.

  • Check the recent log messages for new errors. Compare against the log from before the update so you are reacting to changes, not background noise.

  • Click through the one contrib feature you trust least. Everybody has one module that breaks every third update. Test it first, not last.

Time-box testing to thirty minutes for routine updates. If everything on the list passes, ship it. Perfectionism here just delays the security fix you already decided was urgent.

When It Breaks: Roll Back Calmly

Sometimes staging passes and production still breaks. Different data, different traffic, a module that behaves differently under load. This is why you prepared, so execute the plan instead of improvising.

First, decide fast using a timebox. Give the fix fifteen minutes. If you understand the failure and the repair is small, do it. If you are still diagnosing when the timer ends, roll back. A reverted site that works beats a patched site that does not, and you can investigate without visitors watching.

Rolling back means restoring the code, the database, and the files from the pre-update backup, in that order, then clearing caches and re-running your smoke tests. Because you verified the backup before starting, this is a procedure, not a prayer. Announce it plainly in your team channel: what broke, that you are rolling back, and when the next update will be. Calm, factual updates keep everyone else calm too.

Afterward, do the learning while it is fresh. Reproduce the break on staging, find the actual conflict, and write down the fix. The next patch then includes the answer instead of rediscovering the problem. Teams that do this find that rollbacks get rarer every quarter, which is the whole point.

Make It Monthly With a Runbook

Heroic patching fails the moment the hero is on vacation. Turn this workflow into a team habit with two mechanisms: a schedule and a runbook.

Put patch review on the calendar monthly, outside of emergencies. Somebody checks for new Drupal core and contrib advisories, triages them by severity, and schedules the next window. Monthly is frequent enough that each update is small and calm, and rare enough that nobody dreads it. Emergency advisories like PHP2Shell simply pull the next window forward instead of creating chaos from nothing.

Then write the workflow down as a runbook, following the anatomy in the support runbooks guide: trigger, symptoms, ordered steps, exact commands, escalation. Your patch runbook links the backup location, the staging address, the smoke-test list, and the rollback steps. New teammates run their first patch from the page instead of shadowing someone for a quarter, and the team stops depending on whoever remembers how it goes.

What the Habit Earns You

Add it up and the payoff is bigger than any single patch. Your site spends its life within weeks of current instead of months behind, which shrinks every future update. Your team stops fearing patch day because the process has absorbed the surprises. Your customers never learn your update schedule because there is never anything to notice.

And when the next PHP2Shell lands, and it will, the day looks very different. Read the advisory over coffee, pull the window forward, run the checklist, verify, done. No panic, no all-nighter, no apology post. That calm is not luck. It is what a monthly habit buys you, one boring patch day at a time.

Related reading

PHP2Shell: The Critical PHP Flaw Every Website Owner Must Fix Now
security

PHP2Shell: The Critical PHP Flaw Every Website Owner Must Fix Now

October 23, 2026
beginnersphpsecurityserver-hardening
Read →

Comments

Comments disabled — configure NEXT_PUBLIC_GISCUS_* env vars.