97 lines
6.2 KiB
Markdown
97 lines
6.2 KiB
Markdown
# Backup Script Manager
|
|
|
|
A single-administrator web application that runs ordered, typed backup steps on home-lab hosts over SSH and retrieves artifacts over SFTP.
|
|
|
|
Supported operations:
|
|
|
|
- Combine up to 50 Docker commands, remote host commands, database dumps, and directory archives in one job.
|
|
- Execute commands with zero or more declared outputs, allowing preparation and cleanup steps.
|
|
- Create compressed PostgreSQL or MySQL dumps using tools installed on the remote host.
|
|
- Archive a remote directory as `tar.gz`.
|
|
- Export restore-ready Backup Manager configuration with encrypted credential envelopes.
|
|
- Run jobs manually or with timezone-aware cron schedules.
|
|
- Retain a configured number of successful runs and notify by webhook or SMTP.
|
|
- Browse retained executions by job and download their artifacts with recorded SHA-256 checksums.
|
|
|
|
## Run With Docker Compose
|
|
|
|
Create the deployment configuration and a permanent encryption key:
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
openssl rand -base64 32
|
|
```
|
|
|
|
Set the generated value as `MASTER_KEY` and choose a strong `ADMIN_PASSWORD` in `.env`, then start the application:
|
|
|
|
```bash
|
|
docker compose up --build -d
|
|
```
|
|
|
|
Open `http://localhost:3000`. The default binds only to loopback. For network access, put the application behind an HTTPS reverse proxy, set `BIND_ADDRESS` as needed, and set `SECURE_COOKIE=true`; do not expose the HTTP login directly to the LAN.
|
|
|
|
Compose uses managed volumes by default. To use bind mounts, set `DATA_PATH` and `BACKUP_PATH` in `.env`; the process runs as UID/GID `10001`, so those host directories must already exist and be writable by that identity. Keep `MASTER_KEY` in a password manager: losing or changing it makes stored SSH and database credentials unreadable.
|
|
|
|
## Remote Host Requirements
|
|
|
|
- SSH must allow password or private-key authentication and the same account must support SFTP.
|
|
- Verify a probed SSH fingerprint against the host itself, for example with `ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub -E sha256`, before saving it.
|
|
- The account needs write access to `/tmp` and read access to backup sources.
|
|
- Docker jobs require `docker`, `tar`, and `gzip`; the SSH account must be permitted to run Docker without an interactive prompt.
|
|
- Directory jobs require `tar` and `gzip`.
|
|
- PostgreSQL jobs require `pg_dump` and `gzip` on the SSH host. MySQL jobs require `mysqldump` and `gzip`.
|
|
|
|
Docker jobs execute in an existing container. Each configured output is a path inside that container. The manager copies it to a permission-restricted remote staging directory, downloads it, and deletes only that staging directory; it does not delete the original container output.
|
|
|
|
## Job Steps
|
|
|
|
Every job targets one SSH host and runs its steps sequentially over one pinned connection. Use the step arrows in the job builder to control order. Available steps are:
|
|
|
|
- **Docker command:** runs an executable with explicit arguments inside an existing container. Declared container outputs are copied with `docker cp`.
|
|
- **Remote command:** runs an executable with explicit arguments on the SSH host. It can collect generated host files or archives.
|
|
- **PostgreSQL/MySQL dump:** creates a compressed dump using an encrypted password associated with that step.
|
|
- **Directory archive:** archives an absolute host path.
|
|
- **Backup Manager configuration:** creates a local, integrity-protected JSON artifact containing hosts, jobs, schedules, and notification settings. Credential values remain encrypted and restoration requires the original `MASTER_KEY`; the key itself is never exported.
|
|
|
|
Command arguments are entered one per line and are passed as distinct shell-quoted values; shell pipelines and redirection are not interpreted. Add an explicit script on the remote system when more complex command logic is required.
|
|
|
|
By default, a failed step stops the job and no artifacts are published. Enable **Continue if this step fails** only for non-critical steps. The run then continues, skips outputs from the failed step, and finishes as `succeeded_with_warnings` if all required steps complete. Artifact names must be unique across the job, and every job must contain at least one artifact-producing step.
|
|
|
|
Schedules use five-field cron syntax. Jobs do not overlap: a scheduled occurrence is skipped if that job is already queued or running. Runs from different jobs are processed serially in this initial single-instance release.
|
|
|
|
Completed runs with artifacts can be pinned from the **Artifacts** page or the run detail view. Pinned runs are excluded from automatic retention, so they are kept in addition to the configured number of ordinary successful runs. Unpinning makes a run eligible for pruning after the next successful execution. Deleting a job explicitly also deletes its pinned runs and artifacts.
|
|
|
|
## Local Development
|
|
|
|
Node.js 22 or later is required.
|
|
|
|
```bash
|
|
npm install
|
|
export ADMIN_PASSWORD=development-only
|
|
export MASTER_KEY="$(openssl rand -base64 32)"
|
|
npm run dev
|
|
```
|
|
|
|
Vite serves the UI on `http://localhost:5173` and proxies API requests to port `3000`.
|
|
|
|
Verification commands:
|
|
|
|
```bash
|
|
npm run lint
|
|
npm run typecheck
|
|
npm test
|
|
npm run build
|
|
```
|
|
|
|
Run all checks in that order with `npm run check`.
|
|
|
|
## Storage
|
|
|
|
- `data/app.db` contains hosts, encrypted secrets, job definitions, schedules, and run history.
|
|
- `backups/<job-id>/<run-id>/` contains completed artifacts.
|
|
- `backups/.staging/` contains in-progress downloads and is cleaned when a run fails.
|
|
|
|
Configuration exports omit run history, artifact metadata, artifact files, the administrator password, runtime paths, and `MASTER_KEY`. Store the exported JSON and the key separately. For a complete storage-level backup, back up both the data and artifact volumes together.
|
|
|
|
Restore a configuration export from **Settings > Restore configuration**. Restores require the original `MASTER_KEY`, reject modified exports, update records with matching stable identities, add missing records, and leave unrelated local configuration and run history untouched. Numeric IDs and host references are remapped when necessary. A backup from another manager can initialize an empty installation but cannot merge into a populated installation. Restore is blocked while any job is queued or running, and conflicting names owned by unrelated local records must be resolved first.
|