Automate Free MySQL Database Backups on VPS Using Laravel Cron Job
Option 1: Use Laravel’s Spatie/db-dumper
Package (Recommended)
This is the best and most secure alternative.
Step 1: Install the package
composer require spatie/db-dumper
Step 2: Use it in your command or controller
use Spatie\DbDumper\Databases\MySql;
public function handle()
{
$filename = "backup-" . now()->format('Y-m-d-H-i-s') . ".sql";
$path = storage_path("app/backup/{$filename}");
MySql::create()
->setDbName(env('DB_DATABASE'))
->setUserName(env('DB_USERNAME'))
->setPassword(env('DB_PASSWORD'))
->setHost(env('DB_HOST'))
->dumpToFile($path);
$this->info("Backup created: {$path}");
}
Advantages:
- No raw shell commands
- Handles passwords securely
- Works cross-platform (Windows/Linux)
- Easy to extend for compression or S3 uploads
Option 2: Use Laravel’s Built-in Artisan Command + Database Config
If you want to create a simple internal backup command with error-handling:
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
public function handle()
{
$filename = "backup-" . now()->format('Y-m-d-H-i-s') . ".sql";
$path = storage_path("app/backup/{$filename}");
try {
$connection = DB::connection()->getPdo();
$command = sprintf(
'mysqldump --user=%s --password=%s --host=%s %s > %s',
escapeshellarg(env('DB_USERNAME')),
escapeshellarg(env('DB_PASSWORD')),
escapeshellarg(env('DB_HOST')),
escapeshellarg(env('DB_DATABASE')),
escapeshellarg($path)
);
exec($command, $output, $returnVar);
if ($returnVar !== 0) {
throw new \Exception("Backup failed.");
}
$this->info("Backup successful: {$filename}");
} catch (\Throwable $e) {
$this->error("Error: " . $e->getMessage());
}
}
Advantages:
- Adds error handling
- Escapes arguments safely
- Still uses
mysqldump
but with better hygiene
Option 3: Database Export + Upload to Cloud (S3 / Google Drive)
If you want to store backups externally, extend Option 1 like this:
use Spatie\DbDumper\Databases\MySql;
use Illuminate\Support\Facades\Storage;
public function handle()
{
$filename = "backup-" . now()->format('Y-m-d-H-i-s') . ".sql";
$localPath = storage_path("app/backup/{$filename}");
MySql::create()
->setDbName(env('DB_DATABASE'))
->setUserName(env('DB_USERNAME'))
->setPassword(env('DB_PASSWORD'))
->setHost(env('DB_HOST'))
->dumpToFile($localPath);
// Upload to S3
Storage::disk('s3')->put("db_backups/{$filename}", file_get_contents($localPath));
$this->info("Backup uploaded to S3: db_backups/{$filename}");
}
Summary of Options
Option | Method | Security | Portability | Best For |
---|---|---|---|---|
1 | Spatie/db-dumper | ✅ Safe | ✅ Works everywhere | Laravel production use |
2 | Enhanced exec() | ⚠️ Medium | ⚠️ Depends on shell | Simple local use |
3 | Spatie + Cloud Upload | ✅✅ High | ✅ Works anywhere | Automated offsite backups |
At Online Learner, we're on a mission to ignite a passion for learning and empower individuals to reach their full potential. Founded by a team of dedicated educators and industry experts, our platform is designed to provide accessible and engaging educational resources for learners of all ages and backgrounds.
Terms Disclaimer About Us Contact Us
Copyright 2023-2025 © All rights reserved.