Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PHP Encrypted Backup Service

A production backup and restore service for PHP applications on shared hosting — where you have no root, no mysqldump guarantee, no supervisor, and a process manager that will kill a long-running PHP script without warning.

Creates verified, encrypted, integrity-checked snapshots of the database and application files, and restores them from the CLI.


Why it exists

Most PHP backup scripts are twenty lines that tar a folder and dump a database. They work until the day you need them, which is the day you discover the archive was truncated because the host killed the process at 300 seconds, or that nobody ever tested the restore path.

This service is built around the failure modes rather than the happy path:

  • The host kills long processes. A backup that dies mid-run leaves a running row in the database forever, and the next run refuses to start because one is "already in progress." reconcileStaleRuns() sweeps rows that have been running past a grace window and marks them failed with a clear reason, so the system unblocks itself instead of needing a human.
  • Two processes can overlap. Rolling deployments and cron overlap start a second backup on top of the first. An OS-level file lock prevents that, alongside the database status row.
  • An archive can be corrupt and still look fine. The archive is hashed before encryption and verified again after by streaming authenticated decryption into a hash context — so a snapshot is only marked good once it has been proven decryptable and intact.
  • Verification must not need twice the disk. That second verification streams rather than writing a full temporary archive, because shared hosting quotas are exactly where you can least afford a 2× disk spike.

Encryption

Archives are encrypted with a per-installation master key using libsodium where available, falling back to OpenSSL. Both are authenticated — a tampered or truncated archive fails verification rather than decrypting to garbage.

Each archive carries a magic header identifying which cipher produced it (PHPBACKUP2-SODIUM / PHPBACKUP2-OPENSSL), so the restore path selects the right one without being told.

The archive is assembled outside the public web root. If your backups are reachable over HTTP, you do not have backups; you have a public database export.


What's in here

src/Services/BackupService.php   the service — run, encrypt, verify, prune, reconcile
src/Core/Config.php              configuration access
src/Core/Database.php            thin PDO wrapper (run / one / all)
src/Core/Logger.php              file logger
src/Core/Release.php             release version resolution
bin/restore-backup.php           CLI restore — decrypt, verify, unpack, import
bin/_cli_bootstrap.php           CLI autoload/bootstrap
examples/admin-backups-page.php  an admin UI page driving the service
config.example.php               configuration template

Off-site upload to Google Drive is connected through OAuth in the host application's integrations screen; that wiring is not included here, but the service exposes the hooks for it.


Usage

use App\Services\BackupService;

BackupService::reconcileStaleRuns();      // clear snapshots killed mid-run
$run = BackupService::start();            // create, encrypt and verify a snapshot
$active = BackupService::activeRun();     // null when nothing is running

Restore from the CLI:

php bin/restore-backup.php --file=/path/to/snapshot.enc --confirm

Requirements: PHP 8.0+, PDO MySQL, and either ext-sodium (preferred) or ext-openssl.


Before you rely on it

Restore, on a scratch database, on a schedule. An untested backup is a belief, not a backup — and this service exists because that belief is usually wrong.

Store the master key somewhere other than the server being backed up. A key sitting next to the archives protects you from nothing that actually happens.


Notes on this repository

Extracted and generalised from the release infrastructure of a production platform built under contract. The client's application code, business logic, database schema and branding are not included — this is the backup subsystem and the minimal core it depends on. Namespaces were rebased from the original vendor namespace to App\, and the archive magic header renamed, so archives produced by the original deployment are not interchangeable with this build.


Licence

MIT — see LICENSE.

About

Verified encrypted backups for PHP apps on shared hosting

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages