Automatic Backups
Set up and manage automatic backup schedules for your WordPress site
Automatic Backups
Configure automatic backup schedules to ensure your WordPress site is continuously protected. Set up daily, weekly, or custom backup schedules with minimal manual intervention.
Automated Backup Setup
Basic Configuration
Enable Automatic Backups
// Enable automatic backups in wp-config.php
define('WP_AUTO_BACKUP_ENABLED', true);
define('WP_BACKUP_FREQUENCY', 'daily'); // daily, weekly, monthly
define('WP_BACKUP_TIME', '02:00'); // 2 AM server time
define('WP_BACKUP_RETENTION', 30); // Keep backups for 30 daysBackup Storage Configuration
// Configure backup storage
define('WP_BACKUP_STORAGE_TYPE', 'local'); // local, ftp, s3, dropbox
define('WP_BACKUP_STORAGE_PATH', '/path/to/backups/');
define('WP_BACKUP_COMPRESSION', 'gzip'); // gzip, zip, none
define('WP_BACKUP_ENCRYPTION', false); // true to enable encryptionAdvanced Scheduling
Cron-Based Scheduling
// Schedule automatic backups
function setup_backup_schedule() {
// Daily backups
if (!wp_next_scheduled('daily_backup_event')) {
wp_schedule_event(strtotime('02:00:00'), 'daily', 'daily_backup_event');
}
// Weekly backups (Sunday at 3 AM)
if (!wp_next_scheduled('weekly_backup_event')) {
wp_schedule_event(strtotime('next Sunday 03:00:00'), 'weekly', 'weekly_backup_event');
}
// Monthly backups (1st of month at 4 AM)
if (!wp_next_scheduled('monthly_backup_event')) {
wp_schedule_event(strtotime('first day of next month 04:00:00'), 'monthly', 'monthly_backup_event');
}
}
add_action('wp', 'setup_backup_schedule');
// Execute backup functions
function execute_daily_backup() {
perform_automated_backup('daily');
}
function execute_weekly_backup() {
perform_automated_backup('weekly');
}
function execute_monthly_backup() {
perform_automated_backup('monthly');
}
add_action('daily_backup_event', 'execute_daily_backup');
add_action('weekly_backup_event', 'execute_weekly_backup');
add_action('monthly_backup_event', 'execute_monthly_backup');Custom Schedule Intervals
// Register custom cron intervals
function add_custom_cron_intervals($schedules) {
// Every 6 hours
$schedules['six_hours'] = array(
'interval' => 21600, // 6 hours in seconds
'display' => __('Every 6 Hours')
);
// Every 12 hours
$schedules['twelve_hours'] = array(
'interval' => 43200, // 12 hours in seconds
'display' => __('Every 12 Hours')
);
// Twice daily
$schedules['twice_daily'] = array(
'interval' => 43200,
'display' => __('Twice Daily')
);
return $schedules;
}
add_filter('cron_schedules', 'add_custom_cron_intervals');
// Schedule custom interval backups
if (!wp_next_scheduled('custom_backup_event')) {
wp_schedule_event(time(), 'six_hours', 'custom_backup_event');
}
add_action('custom_backup_event', 'execute_custom_backup');Backup Content Configuration
Selective Backup Options
Database-Only Backups
function create_database_backup($schedule_type) {
global $wpdb;
$tables = array(
'posts' => $wpdb->posts,
'postmeta' => $wpdb->postmeta,
'users' => $wpdb->users,
'usermeta' => $wpdb->usermeta,
'options' => $wpdb->options,
'comments' => $wpdb->comments,
'commentmeta' => $wpdb->commentmeta
);
$backup_data = array();
foreach ($tables as $name => $table) {
$results = $wpdb->get_results("SELECT * FROM {$table}", ARRAY_A);
$backup_data[$name] = $results;
}
$filename = 'db_backup_' . $schedule_type . '_' . date('Y-m-d_H-i-s') . '.sql';
$filepath = WP_CONTENT_DIR . '/backups/' . $filename;
// Create backup directory if it doesn't exist
wp_mkdir_p(dirname($filepath));
// Write SQL dump
$sql_content = generate_sql_dump($backup_data);
file_put_contents($filepath, $sql_content);
return $filepath;
}Files-Only Backups
function create_files_backup($schedule_type) {
$source_dir = ABSPATH;
$backup_dir = WP_CONTENT_DIR . '/backups/files_' . $schedule_type . '_' . date('Y-m-d_H-i-s');
// Create backup directory
wp_mkdir_p($backup_dir);
// Files and directories to include
$include_paths = array(
'wp-content/themes/',
'wp-content/plugins/',
'wp-content/uploads/',
'wp-includes/',
'wp-admin/',
'wp-config.php',
'.htaccess'
);
// Files and directories to exclude
$exclude_patterns = array(
'wp-content/cache/',
'wp-content/backups/',
'*.log',
'wp-content/debug.log'
);
foreach ($include_paths as $path) {
$full_path = $source_dir . $path;
if (file_exists($full_path)) {
if (is_dir($full_path)) {
// Copy directory
copy_directory_recursive($full_path, $backup_dir . '/' . $path);
} else {
// Copy file
copy($full_path, $backup_dir . '/' . $path);
}
}
}
return $backup_dir;
}Full Site Backups
function create_full_site_backup($schedule_type) {
// Create database backup
$db_backup = create_database_backup($schedule_type);
// Create files backup
$files_backup = create_files_backup($schedule_type);
// Combine into single archive
$archive_name = 'full_backup_' . $schedule_type . '_' . date('Y-m-d_H-i-s') . '.tar.gz';
$archive_path = WP_CONTENT_DIR . '/backups/' . $archive_name;
// Create compressed archive
create_backup_archive($db_backup, $files_backup, $archive_path);
// Clean up temporary files
unlink($db_backup);
remove_directory_recursive($files_backup);
return $archive_path;
}Backup Storage Management
Local Storage
function manage_local_backup_storage() {
$backup_dir = WP_CONTENT_DIR . '/backups/';
$max_backups = get_option('max_local_backups', 10);
if (!is_dir($backup_dir)) {
wp_mkdir_p($backup_dir);
return;
}
// Get all backup files
$backup_files = glob($backup_dir . '*.{sql,tar.gz,zip}', GLOB_BRACE);
// Sort by modification time (newest first)
usort($backup_files, function($a, $b) {
return filemtime($b) - filemtime($a);
});
// Remove old backups if we have too many
if (count($backup_files) > $max_backups) {
$files_to_remove = array_slice($backup_files, $max_backups);
foreach ($files_to_remove as $file) {
unlink($file);
}
}
}Remote Storage Options
FTP/SFTP Upload
function upload_backup_to_ftp($backup_path, $ftp_config) {
$ftp_connection = ftp_connect($ftp_config['host']);
if (!$ftp_connection) {
return new WP_Error('ftp_connection_failed', 'Could not connect to FTP server');
}
$login_result = ftp_login($ftp_connection, $ftp_config['username'], $ftp_config['password']);
if (!$login_result) {
return new WP_Error('ftp_login_failed', 'FTP login failed');
}
// Enable passive mode
ftp_pasv($ftp_connection, true);
// Change to backup directory
if (isset($ftp_config['directory'])) {
ftp_chdir($ftp_connection, $ftp_config['directory']);
}
// Upload file
$remote_filename = basename($backup_path);
$upload_result = ftp_put($ftp_connection, $remote_filename, $backup_path, FTP_BINARY);
ftp_close($ftp_connection);
if (!$upload_result) {
return new WP_Error('ftp_upload_failed', 'FTP upload failed');
}
return true;
}Cloud Storage Integration
// Upload to Amazon S3
function upload_backup_to_s3($backup_path, $s3_config) {
require_once 'vendor/autoload.php'; // AWS SDK
$s3_client = new Aws\S3\S3Client(array(
'version' => 'latest',
'region' => $s3_config['region'],
'credentials' => array(
'key' => $s3_config['access_key'],
'secret' => $s3_config['secret_key']
)
));
try {
$result = $s3_client->putObject(array(
'Bucket' => $s3_config['bucket'],
'Key' => basename($backup_path),
'SourceFile' => $backup_path,
'ACL' => 'private'
));
return $result['ObjectURL'];
} catch (Exception $e) {
return new WP_Error('s3_upload_failed', $e->getMessage());
}
}Backup Verification and Testing
Automated Backup Verification
function verify_backup_integrity($backup_path) {
$verification_results = array(
'exists' => false,
'readable' => false,
'size' => 0,
'checksum' => '',
'corrupted' => false
);
// Check if file exists
if (!file_exists($backup_path)) {
return $verification_results;
}
$verification_results['exists'] = true;
// Check if file is readable
if (!is_readable($backup_path)) {
return $verification_results;
}
$verification_results['readable'] = true;
// Get file size
$verification_results['size'] = filesize($backup_path);
// Generate checksum
$verification_results['checksum'] = hash_file('sha256', $backup_path);
// Additional checks based on file type
$file_extension = pathinfo($backup_path, PATHINFO_EXTENSION);
if ($file_extension === 'sql') {
$verification_results['is_valid_sql'] = verify_sql_backup($backup_path);
} elseif (in_array($file_extension, array('tar', 'gz', 'zip'))) {
$verification_results['is_valid_archive'] = verify_archive_backup($backup_path);
}
return $verification_results;
}Backup Testing
function test_backup_restoration($backup_path) {
$test_results = array(
'database_test' => false,
'files_test' => false,
'overall_success' => false
);
// Create temporary test environment
$test_dir = WP_CONTENT_DIR . '/backup-test-' . time();
wp_mkdir_p($test_dir);
try {
$file_extension = pathinfo($backup_path, PATHINFO_EXTENSION);
if ($file_extension === 'sql') {
// Test database restoration
$test_results['database_test'] = test_database_restore($backup_path, $test_dir);
} elseif (in_array($file_extension, array('tar', 'gz', 'zip'))) {
// Test archive extraction
$test_results['files_test'] = test_archive_extraction($backup_path, $test_dir);
} elseif (is_dir($backup_path)) {
// Test directory copy
$test_results['files_test'] = test_directory_copy($backup_path, $test_dir);
}
$test_results['overall_success'] = $test_results['database_test'] || $test_results['files_test'];
} catch (Exception $e) {
error_log('Backup test failed: ' . $e->getMessage());
} finally {
// Clean up test directory
remove_directory_recursive($test_dir);
}
return $test_results;
}Monitoring and Notifications
Backup Status Monitoring
function monitor_backup_status() {
$last_backup_time = get_option('last_backup_time');
$backup_status = get_option('last_backup_status');
$consecutive_failures = get_option('consecutive_backup_failures', 0);
// Check if backups are running regularly
$hours_since_last_backup = (time() - $last_backup_time) / 3600;
if ($hours_since_last_backup > 25 && $backup_status === 'success') { // More than 25 hours for daily backups
// Backup is overdue
send_backup_overdue_notification($hours_since_last_backup);
}
// Check for consecutive failures
if ($backup_status === 'failed') {
$consecutive_failures++;
update_option('consecutive_backup_failures', $consecutive_failures);
if ($consecutive_failures >= 3) {
send_backup_failure_alert($consecutive_failures);
}
} else {
// Reset consecutive failures on success
update_option('consecutive_backup_failures', 0);
}
}
add_action('backup_status_check', 'monitor_backup_status');Email Notifications
function send_backup_notification($backup_type, $status, $details = array()) {
$admin_email = get_option('admin_email');
$site_name = get_bloginfo('name');
$subject = ucfirst($status) . ': ' . ucfirst($backup_type) . ' Backup - ' . $site_name;
$message = "
<h3>Backup Notification</h3>
<p><strong>Backup Type:</strong> {$backup_type}</p>
<p><strong>Status:</strong> " . ucfirst($status) . "</p>
<p><strong>Time:</strong> " . current_time('mysql') . "</p>
";
if (!empty($details)) {
$message .= "<h4>Details:</h4><ul>";
foreach ($details as $key => $value) {
$message .= "<li><strong>" . ucfirst(str_replace('_', ' ', $key)) . ":</strong> {$value}</li>";
}
$message .= "</ul>";
}
$headers = array('Content-Type: text/html; charset=UTF-8');
wp_mail($admin_email, $subject, $message, $headers);
}Backup Performance Optimization
Resource Management
function optimize_backup_performance() {
// Increase PHP limits for backup operations
if (defined('DOING_BACKUP') && DOING_BACKUP) {
ini_set('memory_limit', '512M');
ini_set('max_execution_time', 300);
ini_set('max_input_time', 300);
}
// Disable unnecessary plugins during backup
if (wp_doing_cron() && isset($_GET['doing_backup'])) {
add_filter('option_active_plugins', 'disable_plugins_during_backup');
}
}
function disable_plugins_during_backup($plugins) {
$plugins_to_disable = array(
'wordpress-seo/wp-seo.php', // Yoast SEO
'w3-total-cache/w3-total-cache.php', // W3 Total Cache
// Add other resource-intensive plugins
);
return array_diff($plugins, $plugins_to_disable);
}Incremental Backup Optimization
function create_incremental_backup($last_backup_time) {
global $wpdb;
// Get changes since last backup
$changed_posts = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$wpdb->posts} WHERE post_modified > %s",
date('Y-m-d H:i:s', $last_backup_time)
));
$changed_postmeta = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$wpdb->postmeta} pm
INNER JOIN {$wpdb->posts} p ON pm.post_id = p.ID
WHERE p.post_modified > %s",
date('Y-m-d H:i:s', $last_backup_time)
));
// Get changed media files
$changed_media = get_changed_media_files($last_backup_time);
// Create incremental backup archive
return create_incremental_archive($changed_posts, $changed_postmeta, $changed_media);
}
function get_changed_media_files($since_timestamp) {
$args = array(
'post_type' => 'attachment',
'posts_per_page' => -1,
'date_query' => array(
array(
'after' => date('Y-m-d H:i:s', $since_timestamp),
'column' => 'post_modified'
)
)
);
$changed_media = get_posts($args);
return $changed_media;
}Security Considerations
Backup Encryption
function encrypt_backup($backup_path, $encryption_key) {
$backup_content = file_get_contents($backup_path);
// Generate initialization vector
$iv = openssl_random_pseudo_bytes(16);
// Encrypt the content
$encrypted = openssl_encrypt(
$backup_content,
'AES-256-CBC',
$encryption_key,
0,
$iv
);
// Store IV with encrypted content
$encrypted_with_iv = $iv . $encrypted;
// Save encrypted backup
$encrypted_path = $backup_path . '.encrypted';
file_put_contents($encrypted_path, $encrypted_with_iv);
// Remove original unencrypted file
unlink($backup_path);
return $encrypted_path;
}
function decrypt_backup($encrypted_path, $encryption_key) {
$encrypted_content = file_get_contents($encrypted_path);
// Extract IV from the beginning
$iv = substr($encrypted_content, 0, 16);
$encrypted = substr($encrypted_content, 16);
// Decrypt the content
$decrypted = openssl_decrypt(
$encrypted,
'AES-256-CBC',
$encryption_key,
0,
$iv
);
return $decrypted;
}Best Practices
Backup Strategy Guidelines
- Regular Schedule: Automate daily backups with weekly and monthly archives
- Multiple Locations: Store backups locally and in the cloud
- Encryption: Encrypt sensitive backup data
- Testing: Regularly test backup restoration
- Monitoring: Monitor backup success and performance
Performance Optimization
- Resource Management: Schedule backups during low-traffic periods
- Incremental Backups: Use incremental backups for large sites
- Compression: Compress backups to save storage space
- Cleanup: Automatically remove old backups
Security Best Practices
- Access Control: Limit backup access to authorized users
- Encryption: Encrypt backups both in transit and at rest
- Integrity Checks: Verify backup integrity regularly
- Secure Storage: Use secure storage locations and methods
Automated backup solutions for continuous WordPress protection.