laravel-workkit/config/workkit.php

24 lines
972 B
PHP
Raw Permalink Normal View History

<?php
return [
/*
|--------------------------------------------------------------------------
| Backup Settings
|--------------------------------------------------------------------------
|
| Used by workkit:db:backup, workkit:db:restore and
| workkit:db:prune-backups. The default `path` is storage_path('backups')
| so backups live alongside the rest of the app's storage. `retention_days`
| is the threshold workkit:db:prune-backups uses by default anything
| older than that gets deleted on the next prune run.
|
*/
'backup' => [
'path' => env('WORKKIT_BACKUP_PATH'), // null → storage_path('backups')
'retention_days' => (int) env('WORKKIT_BACKUP_RETENTION_DAYS', 30),
fix(backup): stream through openssl pipe — kills 500MB+ memory exhaustion The pre-1.1.1 pipeline ran each stage as a separate file step: mysqldump → file.sql xz → file.sql.xz (read whole file into memory) Crypt::encryptString(file_get_contents(file.sql.xz)) The third step blew up with "Allowed memory size exhausted" on mid-three-digit-MB compressed dumps because Laravel's Crypt envelope reads the whole input, base64-encodes (+33%), and JSON-wraps it for the MAC. Peak memory was ~3.5× the file size. New pipeline is one shell pipe: bash -c 'set -o pipefail; mysqldump | xz -3 | openssl enc \ -aes-256-cbc -pbkdf2 -iter 600000 -salt -pass env:WK_KEY > out' Zero PHP-side allocation for the payload — the encryption runs in the openssl process, not the PHP heap. The output file format is the standard `openssl enc -salt` format (starts with "Salted__"), so it's also restorable with vanilla openssl on any host: openssl enc -d -aes-256-cbc -pbkdf2 -iter 600000 -pass env:K \ -in backup.sql.xz.enc | xz -d | mysql ... Encryption is still APP_KEY-derived: the base64-stripped APP_KEY is fed to openssl as the passphrase, PBKDF2 (600k iters) stretches it into the AES key. A backup is still only restorable by a deployment that knows the same APP_KEY. Other changes: - xz default level dropped from 9 to 3 (tunable via --xz-level or config('workkit.backup.xz_level')). For SQL dumps -9 buys a few % size at multiples of the time cost; -3 is the sweet spot. - Restore detects and rejects pre-1.1.1 Crypt-format backups with a clear error (those need a one-off Crypt::decryptString, which would hit the same memory wall, so we don't auto-fall-back). - "bad decrypt" / "bad magic" stderr now translates to "APP_KEY mismatch" so operators don't have to recognise openssl errors. Verified end-to-end against the dev DB (981 blogs / 659 users / 209 roles): backup in 1.2s, openssl-format output, restore into throwaway DB matches every spot-checked row count. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 12:26:17 +00:00
// xz compression level. Lower = faster + larger output. 3 is a
// good default for SQL dumps (~10× ratio at ~3× the speed of -9).
'xz_level' => (int) env('WORKKIT_BACKUP_XZ_LEVEL', 3),
],
];