Ubuntu PHP如何实现备份恢复
导读:Ubuntu PHP 备份与恢复实操指南 一 备份范围与策略 建议将备份划分为三层: 代码与资源(网站根目录,如 /var/www/html); 数据库(如 MySQL/MariaDB,使用 mysqldump 导出为 .sql); P...
Ubuntu PHP 备份与恢复实操指南
一 备份范围与策略
- 建议将备份划分为三层:
- 代码与资源(网站根目录,如 /var/www/html);
- 数据库(如 MySQL/MariaDB,使用 mysqldump 导出为 .sql);
- PHP 与运行时配置(如 php.ini、PHP-FPM 配置)。
- 存储与保留:至少保留7天历史,备份文件权限设为600,并同步到异地/云存储。
- 自动化:用 crontab 定时执行备份脚本,并记录日志便于审计与回滚。
二 用 PHP 实现一键备份与恢复
-
备份脚本 backup.php(示例)
- 功能:打包网站目录 + 导出数据库 + 可选 AES-256-CBC 加密 + 保留7天 + 写日志。
- 使用:将脚本放到网站可写目录(如 /var/www/html/tools/),通过 CLI 执行:
/usr/bin/php /var/www/html/tools/backup.php - 注意:Web 访问需做访问控制与权限校验,避免被滥用。
< ?php // 配置区 $backupRoot = '/var/backups/php_site'; // 备份根目录(确保可写) $wwwRoot = '/var/www/html'; // 网站根目录 $dbHost = 'localhost'; $dbName = 'your_db'; $dbUser = 'your_user'; $dbPass = 'your_password'; $keepDays = 7; $encrypt = true; // 是否加密 $cipher = 'aes-256-cbc'; // 初始化 date_default_timezone_set('Asia/Shanghai'); set_time_limit(300); if (!is_dir($backupRoot)) mkdir($backupRoot, 0700, true); $ts = date('Ymd_His'); $log = "$backupRoot/backup_$ts.log"; $zip = "$backupRoot/site_$ts.zip"; $sql = "$backupRoot/db_$ts.sql"; $enc = "$zip.enc"; function logMsg($msg, $log) { file_put_contents($log, date('Y-m-d H:i:s') . " $msg\n", FILE_APPEND); } // 1) 打包网站文件 $zipOk = false; if (class_exists('ZipArchive')) { $zipArc = new ZipArchive(); if ($zipArc-> open($zip, ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) { $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($wwwRoot, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::LEAVES_ONLY ); foreach ($files as $file) { if (!$file-> isDir()) { $filePath = $file-> getRealPath(); $relativePath = substr($filePath, strlen($wwwRoot) + 1); $zipArc-> addFile($filePath, $relativePath); } } $zipOk = $zipArc-> close(); } } logMsg($zipOk ? "ZIP created: $zip" : "ZIP failed", $log); // 2) 导出数据库 $dumpOk = false; $cmd = sprintf( 'mysqldump --single-transaction --routines --triggers --default-character-set=utf8mb4 -h%s -u%s -p%s %s > %s 2> > %s', escapeshellarg($dbHost), escapeshellarg($dbUser), escapeshellarg($dbPass), escapeshellarg($dbName), $sql, $log ); system($cmd, $ret); $dumpOk = ($ret === 0); logMsg($dumpOk ? "DB dumped: $sql" : "DB dump failed", $log); // 3) 可选加密 $finalArchive = $zip; if ($encrypt & & $zipOk) { $key = random_bytes(32); // 生产环境请安全保存此密钥 $iv = random_bytes(16); $data = file_get_contents($zip); $encData = openssl_encrypt($data, $cipher, $key, OPENSSL_RAW_DATA, $iv); file_put_contents($enc, $iv . $encData); $finalArchive = $enc; @unlink($zip); logMsg("Encrypted -> $enc", $log); } // 4) 清理过期 $files = glob("$backupRoot/*.{ zip,sql,enc,log} ", GLOB_BRACE); foreach ($files as $f) { if (filemtime($f) < time() - $keepDays * 86400) { @unlink($f); logMsg("Removed expired: $f", $log); } } echo "Backup finished. See $log\n"; -
恢复脚本 restore.php(示例)
- 功能:解密(如有)-> 解压覆盖 -> 导入 .sql。
- 使用:将备份包与脚本上传至服务器,执行:
/usr/bin/php /var/www/html/tools/restore.php /var/backups/php_site/site_YYYYMMDD_HHIISS.zip[.enc]
< ?php // 配置区(与备份端一致) $wwwRoot = '/var/www/html'; $dbHost = 'localhost'; $dbName = 'your_db'; $dbUser = 'your_user'; $dbPass = 'your_password'; $cipher = 'aes-256-cbc'; date_default_timezone_set('Asia/Shanghai'); set_time_limit(600); function logMsg($msg, $log) { file_put_contents($log, date('Y-m-d H:i:s') . " $msg\n", FILE_APPEND); } if ($argc < 2) die("Usage: php restore.php < backup.zip|backup.zip.enc> \n"); $archive = $argv[1]; $log = dirname($archive) . '/restore_' . date('Ymd_His') . '.log'; // 1) 解密 $work = $archive; if (pathinfo($archive, PATHINFO_EXTENSION) === 'enc') { $key = ''; // 从安全位置读取密钥(不要硬编码在代码中) if (empty($key) || strlen($key) !== 32) die("Missing or invalid 32-byte key.\n"); $data = file_get_contents($archive); $iv = substr($data, 0, 16); $enc = substr($data, 16); $dec = openssl_decrypt($enc, $cipher, $key, OPENSSL_RAW_DATA, $iv); if ($dec === false) die("Decrypt failed.\n"); $work = $archive . '.dec.zip'; file_put_contents($work, $dec); logMsg("Decrypted -> $work", $log); } // 2) 解压覆盖 $zip = new ZipArchive(); if ($zip-> open($work) !== TRUE) die("Cannot open archive: $work\n"); if (!$zip-> extractTo($wwwRoot)) die("Extract failed.\n"); $zip-> close(); logMsg("Extracted to $wwwRoot", $log); if ($work !== $archive) @unlink($work); // 3) 导入数据库(查找同目录 .sql) $sqlFile = null; foreach (glob(dirname($archive) . '/*.sql') as $f) { if (time() - filemtime($f) < 86400 * 2) { $sqlFile = $f; break; } // 取最近 } if (!$sqlFile) die("No .sql found near $archive\n"); $cmd = sprintf( 'mysql --default-character-set=utf8mb4 -h%s -u%s -p%s %s < %s 2> > %s', escapeshellarg($dbHost), escapeshellarg($dbUser), escapeshellarg($dbPass), escapeshellarg($dbName), $sqlFile, $log ); system($cmd, $ret); logMsg($ret === 0 ? "DB imported: $sqlFile" : "DB import failed", $log); echo "Restore finished. See $log\n"; -
定时任务(crontab)
- 示例:每日 02:00 执行备份,保留 7天,日志与备份统一目录
- 命令:
0 2 * * * /usr/bin/php /var/www/html/tools/backup.php - 建议将备份目录加入 /etc/backup.include 或 .gitignore,避免被代码仓库误提交。
三 系统级备份与恢复 PHP 配置
- 定位配置文件
- 查看加载的 php.ini:
php --ini - 常见路径(按 SAPI 与版本区分):
- CLI:
/etc/php/{ 版本号} /cli/php.ini - FPM:
/etc/php/{ 版本号} /fpm/php.ini与/etc/php/{ 版本号} /fpm/pool.d/*.conf - Apache:
/etc/php/{ 版本号} /apache2/php.ini
- CLI:
- 查看加载的 php.ini:
- 备份
- 打包:
sudo tar -czvf php-fpm-backup-$(date +%Y%m%d).tar.gz /etc/php/*/fpm/php-fpm.conf /etc/php/*/fpm/pool.d/ /etc/php/*/fpm/php.ini - 或 rsync:
sudo rsync -av --progress /etc/php /path/to/backup/php/
- 打包:
- 恢复
- 建议先停服务:
sudo systemctl stop php{ 版本号} -fpm - 解压:
sudo tar -xzvf php-fpm-backup-YYYYMMDD.tar.gz -C / - 或 rsync:
sudo rsync -av --progress /path/to/backup/php/ /etc/php/ - 启动:
sudo systemctl start php{ 版本号} -fpm
- 建议先停服务:
- 版本控制与异地同步
- 对配置目录做 Git 版本管理,记录每次变更与回滚点。
- 用 rsync+SSH 将配置同步到远程主机,提升容灾能力。
四 数据库备份恢复与运维要点
- 数据库备份与恢复
- 备份:
mysqldump -u root -p --single-transaction --routines --triggers --default-character-set=utf8mb4 your_db > backup.sql - 恢复:
mysql -u root -p your_db < backup.sql - 图形化:也可通过 phpMyAdmin 的“导出/导入”完成。
- 备份:
- 安全与合规
- 备份文件权限设为 600,存放于受限目录;加密敏感备份,密钥离线保存。
- 恢复前在测试环境验证;导入前可临时关闭外键检查:
SET FOREIGN_KEY_CHECKS=0;(导入后恢复为 1)。
- 系统级灾难恢复
- 系统镜像:用 Timeshift(BTRFS/RSYNC)或 Clonezilla 做整盘快照/镜像,系统无法启动时可用 Live USB 进入恢复。
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: Ubuntu PHP如何实现备份恢复
本文地址: https://pptw.com/jishu/775541.html
