# Operations [Version francaise](../exploitation.md) ## Docker Execution Docker is the recommended operating mode. The container runs a one-shot command, writes logs to stdout/stderr, generates the PDF report and exits. ### Preparation ```sh cp .env.example .env mkdir -p reports ``` In `.env`, adjust PVE/PBS access and keep the following for Docker execution: ```env REPORT_OUTPUT_DIR=/reports ``` The Docker Compose service mounts `./reports` to `/reports`, making PDFs available on the host in the `reports/` directory. ### Build the Image ```sh docker compose build ``` The image installs Python dependencies and the system libraries required by WeasyPrint. ### Configuration Check ```sh docker compose run --rm pve-backup-report --check-config ``` ### API Connectivity Test ```sh docker compose run --rm pve-backup-report --check-api ``` This command tests `/nodes`, `/storage`, `/cluster` and the endpoint configured in `PVE_BACKUP_JOBS_ENDPOINT`. If `/cluster/backup` returns `HTTP 403 - Permission check failed (/, Sys.Audit)`, the token works but lacks the `Sys.Audit` privilege on `/`. ### PDF Report Generation ```sh docker compose run --rm pve-backup-report --generate-pdf ``` The report is created in `REPORT_OUTPUT_DIR`. The filename contains a timestamp and never overwrites previous reports. Example file generated on the host: ```text reports/rapport-sauvegardes-pve-2026-05-09-020000.pdf ``` ### Docker Diagnostic Commands Inventory: ```sh docker compose run --rm pve-backup-report --dump-inventory ``` Coverage: ```sh docker compose run --rm pve-backup-report --dump-coverage ``` Report data as JSON: ```sh docker compose run --rm pve-backup-report --dump-report-data ``` This output is a technical preview of the report model. Raw sensitive fields are filtered, but the JSON contains operational information such as VM/CT names, VMIDs, PVE notes, servers, datastores, namespaces, PBS users and backup metadata. Treat it as internal data and do not share it outside the authorized operations/audit scope. PBS datastore usage: ```sh docker compose run --rm pve-backup-report --dump-pbs-storage-usages ``` PBS users used by PVE storages: ```sh docker compose run --rm pve-backup-report --dump-pbs-users ``` Diagnostic for a missing latest backup: ```sh docker compose run --rm pve-backup-report --debug-last-backup-vmid ``` Running `docker compose run --rm pve-backup-report` without arguments does not generate a PDF. To produce the report, use `--generate-pdf` explicitly. ## Direct CLI Execution This mode is useful for development or diagnostics outside the container. Local installation: ```sh python3 -m venv .venv . .venv/bin/activate python -m ensurepip --upgrade pip install -r requirements.txt pip install -e . ``` PDF generation uses WeasyPrint. Outside Docker, the host must provide the system libraries required by WeasyPrint. With WeasyPrint 62.x, keep the `pydyf>=0.10,<0.11` constraint to avoid PDF generation errors related to the internal `pydyf` API. Installed commands: ```sh pve-backup-report --check-config pve-backup-report --check-api pve-backup-report --dump-inventory pve-backup-report --dump-coverage pve-backup-report --dump-report-data pve-backup-report --dump-pbs-storage-usages pve-backup-report --dump-pbs-users pve-backup-report --generate-pdf ``` Without editable installation: ```sh PYTHONPATH=src python3 -m pve_backup_report --check-config PYTHONPATH=src python3 -m pve_backup_report --check-api PYTHONPATH=src python3 -m pve_backup_report --dump-inventory PYTHONPATH=src python3 -m pve_backup_report --dump-coverage PYTHONPATH=src python3 -m pve_backup_report --dump-report-data PYTHONPATH=src python3 -m pve_backup_report --dump-pbs-storage-usages PYTHONPATH=src python3 -m pve_backup_report --dump-pbs-users PYTHONPATH=src python3 -m pve_backup_report --generate-pdf ``` In direct local execution, `REPORT_OUTPUT_DIR` can remain `reports/` or point to another directory accessible by the current user. The same `.env` file can be used in Docker and local execution. The Docker value `REPORT_OUTPUT_DIR=/reports` remains valid in the container with the `./reports:/reports` mount. Outside Docker, if `/reports` is not accessible, the application automatically uses the local `reports/` directory and logs the fallback. It is still possible to explicitly force a local path: ```env REPORT_OUTPUT_DIR=reports ``` ## PBS Retention Policy To populate the `Retention policy` table and the `VM/CT backup retention` tables, set the API variables for the relevant PBS: ```env PBS01_NAME=display-name PBS01_API_URL=https://backup.example.invalid:8007 PBS01_API_TOKEN_ID= PBS01_API_TOKEN_SECRET= PBS01_VERIFY_TLS=true ``` For multiple PBS servers, duplicate this block with `PBS02_*`, `PBS03_*`, `PBS04_*`, etc. The report creates retention sections for each configured PBS. Collection reads prune jobs from configured PBS servers through `/config/prune`. If a PBS is unavailable, if its token lacks sufficient rights, or if no policy is returned, the report continues and adds a `pbs_retention` anomaly. Collection also reads snapshots from each configured PBS datastore. Namespaces declared in PVE PBS storages are queried on each PBS, including a secondary PBS that does not directly receive backups from PVE but contains synchronized backups. These data feed the `VM/CT backup retention ` tables, including VM/CT still visible on PBS but absent from the PVE inventory. They are marked `Not active on PVE` in the report. If a PVE namespace does not exist on a tested PBS datastore, the possible `HTTP 400 - Bad Request` returned by PBS is ignored for that non-root namespace to avoid an expected anomaly. Retention tables are split by namespace and also display the datastore, because the same namespace can exist on multiple datastores on the same PBS. They also display the expected version count and a delta compared with visible snapshot count. This calculation depends on an active retention policy matching the same PBS server, datastore and namespace. The report also collects datastore status from each configured PBS to display total, used and free space. The garbage collector status of each PBS datastore is also collected. If the garbage collector is running, a warning is displayed only under retention tables for the relevant PBS/datastore. ## Daily Scheduling Recommended scheduling on Debian 13 can be done with a systemd timer or cron. The container and CLI are designed for one-shot execution: the command generates the report and exits. ### Cron with Docker Compose Example host crontab to run the report every day at 02:00: ```cron SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 0 2 * * * cd /srv/pve-backup-report && /usr/bin/flock -n /tmp/pve-backup-report.lock /usr/bin/docker compose run --rm pve-backup-report --generate-pdf >> /var/log/pve-backup-report.log 2>&1 ``` Important points: - adapt `/srv/pve-backup-report` to the real repository path; - keep `REPORT_OUTPUT_DIR=/reports` in `.env` for Docker; - verify that the host `reports/` directory exists and is accessible; - use `flock` to avoid two simultaneous generations if an execution takes longer than expected; - redirect stdout/stderr to a log file or to the host supervision system. To test the exact scheduled command: ```sh cd /srv/pve-backup-report /usr/bin/flock -n /tmp/pve-backup-report.lock /usr/bin/docker compose run --rm pve-backup-report --generate-pdf ``` ### Cron Calling the Script Directly Example with the project's virtual environment: ```cron SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 0 2 * * * cd /srv/pve-backup-report && /usr/bin/flock -n /tmp/pve-backup-report.lock /srv/pve-backup-report/.venv/bin/pve-backup-report --generate-pdf >> /var/log/pve-backup-report.log 2>&1 ``` In this mode: - `cd` to the repository allows loading the default `.env` file; - `REPORT_OUTPUT_DIR` can remain `/reports`, `reports/`, or point to an absolute path accessible by the cron user; - the cron user must have read access to `.env` and write access to the report directory; - WeasyPrint system libraries must be installed on the host. To test the exact scheduled command: ```sh cd /srv/pve-backup-report /usr/bin/flock -n /tmp/pve-backup-report.lock /srv/pve-backup-report/.venv/bin/pve-backup-report --generate-pdf ``` Adjust the schedule to avoid high-load periods or maintenance windows. ## Daily Verification After execution, check: - presence of a new PDF; - command return code; - container logs; - anomalies section; - list of VM/CT without backup. ## Evidence Retention For audit use, keep reports in a backed-up location. Recommendations: - persistent storage outside the container; - limited write permissions; - read access for authorized people only; - retention aligned with internal policy; - system clock synchronized by NTP. ## Recommended Exit Codes | Code | Meaning | | --- | --- | | `0` | Report generated without blocking error. | | `1` | Configuration error. | | `2` | PVE authentication impossible. | | `3` | PVE API unavailable. | | `4` | PDF write error. | | `5` | Unexpected error. | An execution with non-blocking anomalies can return `0` if the report is generated and anomalies are visible in the PDF. ## Monitoring Monitor at least: - absence of today's report; - command failure; - increase in the number of VM/CT without backup; - recurring anomalies; - PVE token expiration or revocation. ## Log Rotation Logs must remain on stdout/stderr to integrate with Docker. Rotation is handled by Docker or by the operating platform. ## Restore and Audit This report proves the observed configuration at execution time. It does not by itself prove that a restore is possible. For stronger evidence, complement this project with: - checks of latest job executions; - verification of snapshots present in PBS; - periodic restore tests; - signature or immutable storage of reports.