By Greg Nowak. Drush is useful because it makes routine Drupal work repeatable. When an agency takes over a site or an operations lead asks whether a release is ready, the team needs more than a collection of commands: it needs to know which site it is touching, what will change, and how it will recover if something goes wrong.
Used with a short runbook, Drush helps answer those questions. It can establish a baseline, make staging and live targets explicit, and run a consistent deployment sequence. The commands below are a starting point for a team workflow, not a substitute for deciding who owns backups, approvals, and post-release checks.
Keep Drush with the Drupal project
For a Composer-managed site, install Drush as a project dependency and run the binary from the project root. That keeps its version recorded alongside the code in composer.lock. Check the official compatibility table before changing Drupal, PHP, and Drush together: Drush 14 requires PHP 8.3 or newer and is recommended for Drupal 11.3 and later; Drush 13 is recommended for Drupal 10.2 and later and also supports Drupal 11.
composer require drush/drush
vendor/bin/drush --version
vendor/bin/drush core:statusOn an inherited site, check the existing Composer constraints before running composer require. Installing a new Drush major version during an unrelated maintenance task can turn a simple audit into an upgrade.
Start a takeover with facts
Before estimating an upgrade or removing a module, record the Drupal and Drush versions, PHP version, site URI, Drupal root, and configuration sync path. Then list enabled non-core modules. These checks help expose an unexpected runtime, an undocumented extension, or a command pointed at the wrong multisite.
vendor/bin/drush core:status --fields=drupal-version,drush-version,php-version,uri,root,config-sync
vendor/bin/drush pm:list --type=module --status=enabled --no-core
vendor/bin/drush pm:list --type=module --status=enabled --no-core --format=jsonUse JSON when another tool needs the inventory; use the readable table for a review with a developer. Do not treat the list as an automatic removal plan. An enabled module may support a critical editorial task, depend on custom code, or be present for a migration that is still in progress. Review its purpose and ownership before changing it. When sharing status output, select the fields you need rather than exporting every available field, which can include database connection details.
| Moment | Drush check or action | Team decision |
|---|---|---|
| Site takeover | core:status and pm:list |
What is running, and what needs investigation? |
| Release preparation | updatedb:status and config:status |
Are the expected database and configuration changes understood? |
| Environment check | site:alias @self |
Does each command point to the intended site? |
| Deployment | deploy |
Have code, backup, validation, and recovery steps been agreed? |
Make staging and live targets explicit
A shared alias file gives the team consistent names for its environments. Drush documents drush/sites/self.site.yml in the Composer project root. The root value is the Drupal web root, and each uri should match the address used to reach that site in a browser.
live:
host: server.example.com
user: deploy
root: /var/www/example/web
uri: https://www.example.com
stage:
host: stage.example.com
user: deploy
root: /var/www/example/web
uri: https://stage.example.comvendor/bin/drush site:alias @self
vendor/bin/drush @stage core:statusCheck the alias and the reported URI before running a command that changes data. This matters especially for multisite installations, where an incorrect URI can select a different site. Keep passwords and private keys out of the alias file; use the team’s SSH and secret-management arrangements for access. A shared alias also makes handover easier because the next operator can see how environments are addressed.
Make a release a sequence, not a single command
After the intended code has been deployed to staging, inspect pending updates and configuration differences. Resolve surprises there before scheduling production. For Drupal 10.3 and later, Drush’s deploy command runs database updates, configuration import, cache rebuild, and deploy hooks in order; on Drupal 11.2 and later, it also runs cache warming.
vendor/bin/drush @stage updatedb:status
vendor/bin/drush @stage config:status
vendor/bin/drush @stage deploy -yValidate the journeys that matter to the site: for example, an editor publishing a page, a visitor submitting a form, or an integration receiving an event. Once the same code and configuration are ready for production, confirm the release window, a usable backup or recovery point, and who can make the go or stop decision. Then run the documented production step:
vendor/bin/drush @live deploy -ydeploy standardises Drupal’s update steps; it does not create a backup or reverse a database change. The recovery plan must say what to restore, who can restore it, and how the team will confirm the site works afterward. Keep a short record of the code revision, command outcome, and post-release checks so the next person does not have to reconstruct the release from terminal history.
Leave the next team an operating model
A useful handover fits on a page or two: supported Drupal, PHP, and Drush versions; environment aliases; deployment steps; backup ownership; recovery instructions; and the critical journeys to test. Give it a named owner and update it when the site changes. That modest discipline is often more valuable than another clever one-liner.
If your Drupal site depends on undocumented server knowledge or a release process only one person understands, talk to Greg about making its operations easier to inspect, run, and hand over.
Related on GrN.dk
- CMS Upgrades in 2026: Choosing the Right PHP Version for WordPress and Drupal
- Drupal 9: A Practical Upgrade Path for Legacy Sites
- Essential Drupal 8 Modules: What Still Matters on a Legacy Site
Need help with this kind of work?
Talk to Greg about Drupal operations Get in touch with Greg.