putuwahyu29 / backup-bridge
A secure bridge, visual control dashboard, and multi-database backup agent for Laravel applications.
Requires
- php: ^8.2 || ^8.3 || ^8.4
- illuminate/console: ^10.0 || ^11.0 || ^12.0 || ^13.0
- illuminate/filesystem: ^10.0 || ^11.0 || ^12.0 || ^13.0
- illuminate/http: ^10.0 || ^11.0 || ^12.0 || ^13.0
- illuminate/routing: ^10.0 || ^11.0 || ^12.0 || ^13.0
- illuminate/support: ^10.0 || ^11.0 || ^12.0 || ^13.0
- illuminate/view: ^10.0 || ^11.0 || ^12.0 || ^13.0
- symfony/process: ^6.0 || ^7.0 || ^8.0
Requires (Dev)
- mockery/mockery: ^1.6
- orchestra/testbench: ^8.0 || ^9.0 || ^10.0
- phpunit/phpunit: ^10.0 || ^11.0
Suggests
- spatie/laravel-backup: Allows using the Spatie backup driver for advanced backup workflows (^8.0|^9.0|^10.0)
Provides
None
Conflicts
None
Replaces
None
README
Backup Bridge
A secure bridge, visual control dashboard, and multi-database backup agent for Laravel applications.
English | Bahasa Indonesia
📌 Overview
Conventional backup solutions (such as spatie/laravel-backup) excel at generating archive files locally on a single server. However, in enterprise environments managing dozens or hundreds of distributed applications, teams often need a centralized backup workflow that:
- Pulls backups remotely without exposing raw SSH access or public database ports.
- Verifies file integrity using streaming SHA-256 checksums.
- Transfers archives to centralized NAS storage (QNAP / Synology / S3) or WebDAV (Nextcloud / ownCloud) via autonomous worker services.
- Receives round-trip audit confirmation callbacks from external workers.
- Provides a ready-to-use Visual Web Dashboard in the browser with zero complex admin panel dependencies.
Backup Bridge bridges the gap between individual Laravel apps and centralized backup orchestrators.
✨ Features
- 🗄️ Multi-Database Support: Automatic detection for MySQL, PostgreSQL (
pg_dump), and SQLite (zero-dependency file snapshot), with full backward compatibility forspatie/laravel-backup. - 📦 Public Attachments Backup: Automatically compresses public storage directories (
storage/app/public) into a clean.ziparchive. - 🖥️ Built-in Control Dashboard: Responsive web interface (
/admin/backups) to trigger manual backups, download dumps, copy SHA-256 hashes, and monitor worker sync status. - ⚡ Universal Architecture Support: Works out of the box with Full-Stack Blade, Headless REST API, and Laravel Inertia.js (
?json=1). - 🔐 Hardened Security:
- Constant-time
X-API-Keyverification (hash_equals) to prevent timing attacks. - Path-traversal protection and shell parameter sanitization.
- Backups stored in protected private storage (
storage/app/private/).
- Constant-time
- 📡 Audit Callback Feedback Loop: Dedicated endpoint (
POST /api/service-reports) receiving sync status and error logs from puller workers. - 💻 Complete Artisan CLI: Commands including
app-backup:run,app-backup:status,app-backup:install, andapp-backup:key-generate.
🏗️ Architecture
┌─────────────────────────────────┐
│ Laravel Application │
│ (Blade / Inertia / REST API) │
│ │
│ ┌─────────────────────────┐ │
│ │ Backup Bridge │ │
│ │ - /admin/backups (UI) │ │
│ │ - /api/backups (API) │ │
│ └─────────────┬───────────┘ │
└─────────────────┼───────────────┘
│ HTTPS (X-API-Key)
▼
┌─────────────────────────────────┐
│ Backup Puller Worker │
│ (Docker / Node.js Engine) │
│ - SHA-256 Verification │
│ - Auto ZIP Compression │
│ - State Deduplication │
└─────────────────┬───────────────┘
│ Storage Protocol
▼
┌─────────────────────────────────┐
│ Centralized Storage │
│ - QNAP NAS (File Station CGI) │
│ - WebDAV (Nextcloud/ownCloud) │
└─────────────────────────────────┘
⚠️ Important: How Backups are Triggered
Important
Does installing this package immediately create a backup?
Not immediately. While this package is highly Plug and Play in terms of setup and auto-configuration, it operates as a Bridge / Agent rather than an instant background cron running upon composer require.
Backups are executed only when triggered via one of the 4 execution methods below.
🚀 Step-by-Step Setup Guide
1. Install via Composer
composer require putuwahyu29/backup-bridge
2. Run Automatic Installation (One-Command Setup)
This command automatically publishes the configuration and generates a cryptographically secure API key directly into your .env file:
php artisan app-backup:install
3. Secure Web Dashboard in Production
By default, the dashboard uses the ['web'] middleware group. To restrict access to authenticated administrators in production, update config/app-backup.php:
'dashboard' => [ 'enabled' => env('APP_BACKUP_DASHBOARD_ENABLED', true), 'prefix' => env('APP_BACKUP_DASHBOARD_PREFIX', 'admin/backups'), 'middleware' => ['web', 'auth'], // Add your application auth middleware ],
4. Choose Your Backup Execution Method
Select the workflow that matches your infrastructure architecture:
🔄 4 Ways to Trigger / Run Backups
Method 1: Centralized Automation via Remote Worker (Recommended for Multi-App / NAS)
Use the companion microservice @putuwahyu29/backup-puller-worker. The worker handles scheduled pulls, verification, and uploads without placing ongoing cron load on your web server:
- Copy the generated
APP_BACKUP_API_KEYfrom your application's.env. - Add your application to the worker's
apps.json:
{
"apps": [
{
"name": "si-petasls",
"baseUrl": "https://your-app.domain.com",
"apiKey": "bk_xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"cron": "0 2 * * *",
"backupFresh": true
}
]
}
The worker will automatically trigger fresh backups via API, verify the streaming SHA-256 hash, compress them into ZIP, and upload them to your QNAP NAS or Nextcloud/WebDAV.
Method 2: Local Scheduled Automation via Laravel Scheduler (CRON)
If you do not use an external worker and want the Laravel application to regularly back up locally on its own server:
For Laravel 11 / 12 / 13 (routes/console.php):
use Illuminate\Support\Facades\Schedule; // Run database backup daily at 02:00 AM Schedule::command('app-backup:run database --fresh')->dailyAt('02:00'); // Run attachments backup weekly on Sunday at 03:00 AM Schedule::command('app-backup:run attachments --fresh')->weeklyOn(0, '03:00');
For Laravel 10 (app/Console/Kernel.php):
protected function schedule(Schedule $schedule): void { $schedule->command('app-backup:run database --fresh')->dailyAt('02:00'); $schedule->command('app-backup:run attachments --fresh')->weekly(); }
(Ensure your server's system cron has * * * * * php /path-to-app/artisan schedule:run >> /dev/null 2>&1 configured).
Method 3: Manual via Web Dashboard
- Open your browser and navigate to:
http://your-app-domain.test/admin/backups - Click "Generate Database Backup" or "Generate Attachments Backup".
- The backup file will be created on the fly, ready for instant download or SHA-256 inspection.
Method 4: Manual via Artisan CLI
Execute directly from your terminal:
# Generate fresh database dump immediately php artisan app-backup:run database --fresh # Generate fresh attachments zip archive immediately php artisan app-backup:run attachments --fresh # Inspect backup status & worker reports php artisan app-backup:status
🗄️ Server Requirements & Multi-Database Config
The default native driver reads your active database connection (config('database.default')):
A. MySQL / MariaDB
- Requirement:
mysqldumpbinary available on the server / container host PATH. - Environment (
.env):
APP_BACKUP_DRIVER=native MYSQLDUMP_PATH=mysqldump
B. PostgreSQL
- Requirement:
pg_dumpbinary installed on the server / container. - Environment (
.env):
APP_BACKUP_DRIVER=native APP_BACKUP_DB_CONNECTION=pgsql PG_DUMP_PATH=pg_dump
C. SQLite
- Requirement: Zero external dependencies! Directly copies a snapshot of the
.sqlitefile. - Environment (
.env):
APP_BACKUP_DRIVER=native APP_BACKUP_DB_CONNECTION=sqlite
D. Public Attachments Archive
- Requirement: PHP
ext-zipextension (ZipArchive) enabled.
🖥️ Usage in Laravel Inertia.js (Vue/React)
The dashboard controller provides a JSON API response when requested with Accept: application/json or query ?json=1:
// Example in a Vue / React Inertia component: const loadBackupData = async () => { const res = await axios.get('/admin/backups?json=1'); console.log(res.data.data); // dbLatest, attLatest, reports, allBackups, stats };
🔌 API Endpoints for Remote Puller Worker
Protected by the X-API-Key HTTP header:
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/backups/latest/metadata?type={database|attachments} |
Retrieves metadata (filename, size, sha256 checksum, date). Supports &fresh=1. |
GET |
/api/backups/latest/download?filename={filename}&type={type} |
Streams the binary backup archive securely. |
POST |
/api/service-reports |
Receives sync reports from workers (status, uploaded size, errors). |
GET |
/api/service-reports/latest?service={service}&status={status} |
Retrieves the latest audit report. |
🛡️ Security
If you discover any security vulnerabilities, please contact the maintainers directly and avoid opening public issues before a patch is published.
📄 License
This package is open-source software licensed under the MIT License.
Developed by Putu Wahyu & Contributors.