Drupal Core and Modules Update
Drupal uses Composer for dependency management — core and modules update via it. Without Composer (manual install) — migrate to Composer-based setup, otherwise every update is manual operation.
Preparation
# Create DB backup
drush sql:dump --result-file=/backups/drupal-$(date +%Y%m%d).sql --gzip
# Backup files (if no automatic)
tar czf /backups/files-$(date +%Y%m%d).tar.gz /var/www/site/web/sites/default/files
# Enable maintenance mode
drush state:set system.maintenance_mode 1 --input-format=integer
drush cr
Check Available Updates
# Show all available updates
composer outdated "drupal/*"
# Only security updates
drush pm:security
Update Drupal Core
# Update to latest compatible version
composer update drupal/core-recommended drupal/core-composer-scaffold --with-all-dependencies
# Or to specific version
composer require drupal/core-recommended:^10.3 --update-with-all-dependencies
# Apply DB updates
drush updatedb
# Update exported config
drush config:export
git diff config/sync/
Update Modules
# Update all modules at once
composer update "drupal/*" --with-all-dependencies
# Update specific module
composer require drupal/views:^3.14
# After module updates
drush updatedb
drush cr
Major Versions: Drupal 9 → 10 → 11
For major update use Upgrade Status:
composer require drupal/upgrade_status
drush en upgrade_status -y
drush upgrade_status:analyze
Upgrade Status analyzes all modules for target version compatibility, shows deprecated functions in custom code.
# Drupal 9 → 10
composer require drupal/core-recommended:^10 --update-with-all-dependencies
# Deprecated APIs: check via Rector
composer require --dev palantirnet/drupal-rector
vendor/bin/rector process web/modules/custom
Updating Contrib Modules with Breaking Changes
Some modules require manual actions on update:
# Check module CHANGELOG
cat vendor/drupal/webform/CHANGELOG.md | head -100
# Check hook_update_N functions
drush php-eval "print_r(drupal_get_schema_versions('webform'));"
# Apply only specific module updates
drush updatedb --module=webform
Testing After Update
# Restore normal mode
drush state:set system.maintenance_mode 0 --input-format=integer
drush cr
# Run tests (if any)
./vendor/bin/phpunit web/modules/custom
# Check logs for errors
drush watchdog:show --severity=Error --count=50
CI/CD for Automatic Updates
# .github/workflows/security-updates.yml
name: Security Updates
on:
schedule:
- cron: '0 9 * * 1' # every monday
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check security updates
run: composer audit
- name: Apply updates
run: composer update --with-all-dependencies
- name: Create PR if changes
uses: peter-evans/create-pull-request@v6
Timeframes
Planned Drupal core and modules update with backup and testing — 2–4 hours. Major update with compatibility analysis — 1–3 days.







