spatie/laravel-backup 框架不仅可以备份数据库,还能方便的备份文件,以及通知。
https://github.com/spatie/laravel-backup
https://spatie.be/docs/laravel-backup/v10/introduction
安装
composer require spatie/laravel-backup
php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider" --tag=backup-config
备份相关的配置文件在 config/backup.php 里。可以根据自己的情况调整处理。
如果是使用 php 镜像运行的项目,可能会出现下边这样的错误。
Starting backup...\nDumping database test_holovision...\nBackup failed because: The dump process failed with a none successful exitcode.\nExitcode\n========\n127: Command not found\n\nOutput\n======\n\n\nError Output\n============\nsh: 1: mysqldump: not found\n.\n#0 /www/www.holovision.com/vendor/spatie/db-dumper/src/DbDumper.php(200):
就是 mysqldump 不存在。这个需要在镜像里单独安装。推荐装 mariadb 的,不装 mysql 的。
可以进入容器,在容器中安装完成测试。
apt-get update
apt-get install -y --no-install-recommends mariadb-client
rm -rf /var/lib/apt/lists/
确定 ok 的话,可以在构建 php 镜像时,加入 mysqldump 的安装的部分。
# 安装 mariadb-client(内含 mysqldump)
RUN apt-get update && apt-get install -y --no-install-recommends \
mariadb-client \
&& rm -rf /var/lib/apt/lists/*
通过定时任务来进行备份
-
新建 BackupCommand .
php artisan make:command BackupCommand -
填入代码
option('force'); $backupSetting = DatabaseBackupSetting::first(); if (!$backupSetting) { Log::channel('backup')->error('备份设置未配置'); return; } if (!$backupSetting->is_enable && !$force) { Log::channel('backup')->error('备份设置已关闭:' . $force); return; } $last_backup_time = $backupSetting->last_backup_time; if ($last_backup_time) { $need_backup = false; if ($backupSetting->backup_interval == 1) { // 按天进行备份 if (Carbon::parse($last_backup_time)->addDays(1)->addMinutes(-2)->lt(Carbon::now())) { $need_backup = true; } } elseif ($backupSetting->backup_interval == 2) { // 按周进行备份 if (Carbon::parse($last_backup_time)->addweeks(1)->addMinutes(-2)->lt(Carbon::now())) { $need_backup = true; } } elseif ($backupSetting->backup_interval == 3) { // 按月进行备份 if (Carbon::parse($last_backup_time)->addMonths(1)->addMinutes(-2)->lt(Carbon::now())) { $need_backup = true; } } if (!$need_backup) { Log::channel('backup')->info('还未到备份时间', ['now' => Carbon::now()->toDateTimeString(), 'last_backup_time' => $last_backup_time, 'backup_interval' => $last_backup_time]); return; } } Log::channel('backup')->info('数据备份开始:' . $force); $databaseBackupLog = DatabaseBackupLog::create([ 'type' => $force ? 'manual' : 'auto', 'status' => 'running', 'started_at' => Carbon::now()->toDateTimeString() ]); $exitCode = Artisan::call('backup:run', [ '--only-db' => true, ]); $output = Artisan::output(); if ($exitCode != 0) { $databaseBackupLog->update([ 'status' => 'failure' ]); Log::channel('backup')->error('数据备份失败:', [$output]); return; } $databaseBackupLog->update([ 'status' => 'success', 'finished_at' => Carbon::now()->toDateTimeString() ]); $backupSetting->update([ 'last_backup_time' => $databaseBackupLog->started_at ]); Log::channel('backup')->info('数据备份完成', [$output]); } }然后可以去完善定时任务相关的逻辑。
