Drupal Backups and Maintenance — Backup Strategies and Site Upkeep
In this tutorial, you'll learn how to back up and maintain a Drupal site: automated backups using the Backup & Migrate module, manual database and file backups, restoring from backups, managing maintenance mode, configuring cron, and running regular site audits.
What You'll Learn
- Installing and configuring Backup & Migrate module
- Backup types: database only, files only, full site
- Backup destinations: server, FTP, Amazon S3, Dropbox, email, download
- Manual database backups with Drush and phpMyAdmin
- Manual file backups with tar
- Restoring from backup using Drush
- Maintenance mode configuration
- Cron management: DRUSH_CRON, server cron, HTTP cron
- Logs: Recent log messages, watchdog, syslog module
- Update Process: core, modules, database updates
- Content cleanup: revisions, logs, old content
- Regular maintenance tasks: daily, weekly, monthly
Why It Matters
Every Drupal site will eventually need a restore. A failed update, a hacked module, a server crash, or accidental content deletion — any of these can take your site offline. Without backups, recovery means rebuilding from scratch. With proper backups, you restore in minutes. Maintenance is equally important: outdated modules, unread logs, and old content revisions accumulate and slow your site down. A regular maintenance routine prevents emergencies.
Real-World Use
An e-commerce site running Drupal Commerce experiences a failed module update that breaks the checkout page. The site is losing revenue every minute. Because the site administrator has automated daily backups stored on Amazon S3 with 30-day retention, they restore the previous day's backup in 15 minutes. The failed module is identified and fixed on staging before being deployed again. Without the backup system, the site would have been offline for hours while developers debugged the issue.
Learning Path
flowchart LR A[Performance Optimization] --> B[Backups and Maintenance] B --> C[Backup Strategies] C --> D[Backup & Migrate Module] D --> E[Manual Backups] E --> F[Restore Process] F --> G[Maintenance Mode] G --> H[Cron Management] H --> I[Site Audits] I --> J[Go-Live Checklist]
Backup & Migrate Module
The Backup & Migrate module provides an automated backup system with a user interface and scheduling:
composer require drupal/backup_migrate
drush pm:enable backup_migrate
After installation, configure at Configuration > Development > Backup & Migrate (/admin/config/development/backup_migrate).
Backup Types
The module supports three backup types:
- Database only: Backs up the MySQL/PostgreSQL database. Fastest option. Use with file backups for full coverage.
- Files only: Backs up the public and private files directories.
- Full site: Backs up both database and files.
Backup Destinations
Configure where backups are stored:
# Backup destinations
- Server Directory: Store in /var/backups/
- FTP/SFTP: Upload to remote server
- Amazon S3: Store in cloud storage
- Dropbox: Store in Dropbox
- Email: Attach to email (small backups only)
- Download: Manual download via browser
# Configure S3 destination via Drush
drush config:set backup_migrate.settings destinations.s3 \
'{"id":"s3","name":"Amazon S3","type":"s3","config":{"bucket":"my-drupal-backups","region":"us-east-1","folder":"daily"}}'
Scheduling Backups
# Create a daily backup schedule
drush config:set backup_migrate.settings schedules.daily \
'{"id":"daily","name":"Daily Backup","type":"schedule","config":{"enabled":true,"frequency":86400,"backup_type":"full","destination_id":"s3"}}'
# Create a weekly database-only backup
drush config:set backup_migrate.settings schedules.weekly_db \
'{"id":"weekly_db","name":"Weekly DB","type":"schedule","config":{"enabled":true,"frequency":604800,"backup_type":"database","destination_id":"s3"}}'
Manual Database Backups
Use Drush for command-line database dumps:
# Basic database dump
drush sql:dump > /var/backups/drupal-db-$(date +%Y-%m-%d).sql
# Compressed dump
drush sql:dump --gzip > /var/backups/drupal-db-$(date +%Y-%m-%d).sql.gz
# Exclude specific tables (cache tables)
drush sql:dump \
--structure-tables-key=common \
--extra-dump="--ignore-table=drupal.cache_*" \
> backup.sql
# Database dump with options
drush sql:dump \
--result-file=/var/backups/daily.sql \
--create-db \
--data-only
Using phpMyAdmin or Adminer:
- Login to phpMyAdmin
- Select the Drupal database
- Click Export
- Choose Quick or Custom export
- Select format: SQL
- Download the file
Manual File Backups
Back up Drupal files using tar:
# Full file backup (entire project)
tar -czf /var/backups/drupal-files-$(date +%Y-%m-%d).tar.gz \
--exclude='./vendor' \
--exclude='./node_modules' \
--exclude='./.git' \
.
# Backup only the web root
tar -czf /var/backups/drupal-web-$(date +%Y-%m-%d).tar.gz \
--exclude='./sites/default/files/*/cache' \
--exclude='./sites/default/files/php' \
web/
# Backup only files directory
tar -czf /var/backups/drupal-files-$(date +%Y-%m-%d).tar.gz \
-C web/sites/default/files .
Restoring from Backup
Database Restore
# Restore from uncompressed SQL
drush sql:cli < /var/backups/drupal-db-2026-06-27.sql
# Restore from compressed SQL
gunzip -c /var/backups/drupal-db-2026-06-27.sql.gz | drush sql:cli
# Drop existing tables first (if starting fresh)
drush sql:drop
drush sql:cli < backup.sql
# Verify restoration
drush sql:query "SELECT COUNT(*) FROM node_field_data"
File Restore
# Extract file backup
tar -xzf /var/backups/drupal-files-2026-06-27.tar.gz
# Restore specific directory
tar -xzf /var/backups/drupal-files-2026-06-27.tar.gz \
-C /var/www/web/sites/default/files/
# Set correct permissions after restore
chown -R www-data:www-data web/sites/default/files/
chmod 755 web/sites/default/files/
Complete Restore Workflow
#!/bin/bash
# Complete restore script
# 1. Maintenance mode
drush state:set system.maintenance_mode 1
# 2. Restore files
tar -xzf backups/drupal-files-2026-06-27.tar.gz -C /var/www/
# 3. Restore database
gunzip -c backups/drupal-db-2026-06-27.sql.gz | drush sql:cli
# 4. Rebuild cache
drush cr
# 5. Verify site
drush status
# 6. Exit maintenance mode
drush state:set system.maintenance_mode 0
Maintenance Mode
Put your site into maintenance mode during updates or emergencies:
# Enable maintenance mode
drush state:set system.maintenance_mode 1
# Or via web UI:
# Configuration > Development > Maintenance mode
# Custom maintenance message
drush config:set system.maintenance message \
"We are performing scheduled maintenance. Please check back in 30 minutes."
# Disable maintenance mode
drush state:set system.maintenance_mode 0
<?php
// Check if site is in maintenance mode in code
$in_maintenance = \Drupal::state()->get('system.maintenance_mode');
if ($in_maintenance) {
// Site is undergoing maintenance
}
Cron Management
Cron runs scheduled tasks like indexing content, cleaning logs, and sending emails:
# Run cron manually
drush cron
# Run cron with verbose output
drush cron --verbose
# Check when cron last ran
drush state:get system.cron_last
Configuring Server Cron
For production, use a system cron job instead of HTTP cron:
# Edit crontab
crontab -e
# Add line (every hour)
0 * * * * /usr/local/bin/drush --root=/var/www/web cron \
>> /var/log/drush-cron.log 2>&1
# Or every 15 minutes
*/15 * * * * /usr/local/bin/drush --root=/var/www/web cron
DRUSH_CRON
Set an environment variable to disable HTTP cron:
<?php
// settings.php: disable HTTP cron
$settings['cron_safe_threshold'] = 0;
// Or via environment variable
// Set DRUSH_CRON=true in your .env file
Cron Safety
<?php
// settings.php: set a cron key for HTTP access
$settings['cron_key'] = 'your-random-cron-key';
// Access: https://example.com/cron/your-random-cron-key
Logs and Monitoring
Recent Log Messages
# View recent log entries via Drush
drush watchdog:show
# Short form
drush ws
# Show last 20 entries
drush ws --count=20
# Filter by severity
drush ws --severity=error
# Tail logs (follow mode)
drush ws --tail
syslog Module
Forward Drupal logs to the system syslog:
drush pm:enable syslog
<?php
// settings.php: syslog configuration
$config['syslog.settings']['identity'] = 'drupal';
$config['syslog.settings']['facility'] = 128; // local0
Log Deletion
# Delete all log entries
drush watchdog:delete all
# Delete entries older than 7 days
drush watchdog:delete --age=604800
Update Process
Updating Core and Modules
# Check for updates
composer outdated drupal/*
drush pm:list --status=not-updated
# Update core
composer update drupal/core-recommended --with-all-dependencies
# Update a specific module
composer update drupal/pathauto --with-all-dependencies
# Apply database updates
drush updatedb
# Clear caches
drush cr
Update Workflow
#!/bin/bash
# Safe update workflow
# 1. Backup before updating
drush sql:dump --gzip > pre-update-db.sql.gz
tar -czf pre-update-files.tar.gz web/
# 2. Maintenance mode on
drush state:set system.maintenance_mode 1
# 3. Update code
composer update drupal/core-recommended --with-all-dependencies
# 4. Apply database updates
drush updatedb
# 5. Import config (if needed)
drush cim
# 6. Clear cache
drush cr
# 7. Check status
drush status
# 8. Maintenance mode off
drush state:set system.maintenance_mode 0
Content Cleanup
Regular cleanup improves performance and reduces storage:
# Delete old content revisions
drush entity:delete node --bundle=article --older-than=365
# Clear old log entries
drush watchdog:delete --age=30
# Remove unused files (via UI: Configuration > Media > File system)
Regular Maintenance Tasks
Daily Tasks
# Run automated backup
drush backup:run
# Check error logs
drush watchdog:show --severity=error
# Verify cron ran
drush state:get system.cron_last
Weekly Tasks
# Check for updates
composer outdated drupal/*
# Review user accounts
drush user:list --status=blocked
# Check disk usage
du -sh web/sites/default/files/
Monthly Tasks
# Full backup
drush sql:dump --gzip > monthly-backup.sql.gz
tar -czf monthly-files.tar.gz web/
# Security check
drush security_review:run
# Delete old content revisions
drush entity:delete node --older-than=365
# Review and clean modules
drush pm:list --status=disabled
# Performance check
# Review slow queries, cache hit rates
Common Mistakes
Only backing up the database, not the files: Database backups are essential, but without the files directory (images, uploaded documents, private files), your site is incomplete. Always back up both.
Not testing backups: A backup that you cannot restore is worthless. Test your restore process on a staging environment at least monthly. Verify that the restored site works.
Storing backups on the same server as the site: If the server crashes, you lose both the site and the backups. Store backups on a different server, cloud storage (S3), or download them locally.
Disabling cron and not setting up an alternative: If HTTP cron is disabled and no system cron is configured, scheduled tasks never run. Content indexing, log cleanup, and email sending stop working.
Skipping content cleanup: Old revisions, unread logs, and stale cache tables accumulate over time. A site with years of revisions can have a database many times larger than necessary.
Practice Questions
- What is the difference between a database-only backup and a full backup, and when would you use each?
- Write the Drush command sequence to: put the site in maintenance mode, back up the database, update Drupal core, run database updates, and exit maintenance mode.
- How do you verify that cron has been running correctly on a production site?
- Challenge: Create a complete backup and maintenance plan for a Drupal site. Define: the backup schedule (full vs incremental), retention policy (how long to keep backups), storage destinations (local vs cloud), the restore procedure (step by step), the update workflow (backup before update, maintenance mode, apply changes, test, restore if failed), a monitoring system (cron health check, log alerts, disk usage warnings), and a content cleanup schedule (revisions, logs, unused files).
FAQ
Mini Project
Goal: Set up a complete backup and maintenance system for a Drupal site.
- Install and configure Backup & Migrate with: daily full backup to a server directory, weekly backup to Amazon S3, 30-day retention (delete backups older than 30 days)
- Write a restore script that: accepts a date parameter, restores the database and files from that date's backup, exits maintenance mode after restore, and logs the restore operation
- Set up a system cron job that runs
drush cronevery 15 minutes - Configure syslog to forward Drupal errors to the system log
- Create a maintenance script
maintenance.shthat runs weekly and: checks for security updates, clears old log entries, deletes content revisions older than 6 months, reports disk usage, and emails a summary to the admin - Test the full restore process: take a backup, delete all content on the site, restore from backup, and verify that everything works
What's Next
Now that you can back up and maintain your site, proceed to go-live checklist for a complete pre-launch readiness guide covering security, performance, SEO, and monitoring checks.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro