|
|
il y a 1 mois | |
|---|---|---|
| .. | ||
| backups | il y a 1 mois | |
| .htaccess | il y a 1 mois | |
| README.md | il y a 1 mois | |
| config.sample.php | il y a 1 mois | |
| index.php | il y a 1 mois | |
| lib.php | il y a 1 mois | |
| manage.php | il y a 1 mois | |
| s3.php | il y a 1 mois | |
| upload.php | il y a 1 mois | |
This folder can be deployed as a central backup server for distributed PSA orderform instances.
config.sample.php to config.php.BACKUP_SERVER_PASSWORD.backups/ directory is writable by PHP.index.php or manage.php and log in with the configured password.The upload endpoint is upload.php. It intentionally does not require authentication, but every upload must include an instance identifier that was added in the management UI.
Configure a distributed instance with a managed backup target:
define('BACKUP_REMOTE_TARGETS', [
[
'name' => 'Managed Backup Server',
'type' => 'managed',
'url' => 'https://backup.example.org/upload.php',
'instance' => 'stadt-freising-prod',
],
]);
url must point directly to upload.php. instance may contain letters, numbers, dots, underscores, and dashes.
The server retains the latest backups per instance. The default is 30.
Retention can be changed in config.php with BACKUP_SERVER_RETENTION and in the management UI. The UI value is stored in backups/settings.json and takes precedence after it has been saved once.
Retention is applied after every successful upload and after retention changes in the management UI.
With S3 enabled (see below) this value controls only the local copies. The minimum is 1, so at least the newest backup always stays on local disk.
The server can additionally archive every backup to an S3-compatible object storage (e.g. Hetzner Object Storage, MinIO). Local disk then acts as a small hot cache with the newest backups, while the bucket holds the complete archive.
Enable it in config.php:
define("BACKUP_SERVER_S3_ENABLED", true);
define("BACKUP_SERVER_S3_ENDPOINT", "https://fsn1.your-objectstorage.com");
define("BACKUP_SERVER_S3_REGION", "fsn1");
define("BACKUP_SERVER_S3_BUCKET", "my-backup-bucket");
define("BACKUP_SERVER_S3_PREFIX", "psa-backups");
define("BACKUP_SERVER_S3_ACCESS_KEY", "...");
define("BACKUP_SERVER_S3_SECRET_KEY", "...");
By default the server uses virtual-hosted-style addressing (https://<bucket>.<endpoint>/<key>), which Hetzner and most S3-compatible providers expect. If your provider requires path-style (https://<endpoint>/<bucket>/<key>), set BACKUP_SERVER_S3_PATH_STYLE to true.
Behavior:
<prefix>/<instance>/<filename>.backups/s3.log and shown in the management UI; failed uploads are retried on the next upload for that instance or via the "Retry S3 uploads now" button.BACKUP_SERVER_S3_RETENTION = 365). Backups that age out of S3 are deleted from the bucket.Limitations: uploads to S3 hold the whole file in memory, so a single backup must fit into PHP's memory_limit. Downloads from S3 are streamed and have no such limit. Concurrent uploads for the same instance may race on index.json (pre-existing limitation).
Troubleshooting: S3 errors are written to backups/s3.log with the provider's error code and, on a rejected request, a diagnostic showing the HTTP status chain, any redirect target, and the request id. AccessDenied or a redirect in the status chain usually means the addressing style is wrong — try flipping BACKUP_SERVER_S3_PATH_STYLE. SignatureDoesNotMatch usually means a wrong region or secret key. The server never follows S3 redirects, so a 3xx in the log is reported rather than silently retried against the wrong host.
Backups are stored under:
backups/<instance>/backup-YYYYmmdd-HHMMSS.zip
Metadata is stored in:
backups/index.json
Allowed instances and UI retention settings are stored in:
backups/settings.json
With the included .htaccess, ZIP, JSON, and log files as well as the internal includes (lib.php, s3.php) are not directly readable through Apache. Downloads should use the authenticated management UI.