Automated backup using DAR and par2 for redundancy.
5.1K
π― Stats powered by ClonePulseβ
GitHub: per2jensen/dar-backup-imageβ
Docker Hub: per2jensen/dar-backupβ
dar-backup-image packages dar-backup, dar, PAR2, and their runtime dependencies into a versioned, auditable Docker image.
It has two equally important purposes:
dar, Python tooling, or PAR2 on the host.The second use is deliberate: the image is a restore time capsule. If you need to recover an archive years from now, you can use the packaged toolchain preserved with the backup instead of hunting for compatible packages or reconstructing an old software environment.
For long-term archival use, save a specific versioned image rather than relying only on :latest. The mutable :latest tag is useful for current operations and receives regular security refreshes; a pinned and locally archived version is the artifact you want to retain with your backups.
A helper script, scripts/save-dar-backup-image.shβ , is provided for this purpose. It selects the highest-numbered release or refresh in doc/build-history.jsonβ and saves that versioned image as a compressed tar archive. Its current integrity limitations are documented in Preserve the restore environment with your archivesβ .
The image also works well as an everyday backup runner for cron jobs, systemd timers, and CI pipelines. Its default entrypoint is dar-backup; dar, par2, or an interactive shell can be invoked directly by overriding the entrypoint.
At its core, dar-backup wraps dar and PAR2 for reliable FULL, DIFF, and INCR backups. It validates archives, performs restore tests, manages catalog databases, and can generate redundancy files to protect archives against bit rot.
The image preserves documentation from the installed dar-backup
distribution. It works without network access, backup configuration, or
mounted volumes, so a saved image remains self-documenting years later.
IMAGE=per2jensen/dar-backup:latest
# Discover the documentation (a bare invocation does the same thing)
docker run --rm "$IMAGE" docs
docker run --rm "$IMAGE"
# Display a topic bundled by dar-backup
docker run --rm "$IMAGE" docs overview
docker run --rm "$IMAGE" docs getting-started
# Show paths, component versions, provenance, and project links
docker run --rm "$IMAGE" docs --path
docker run --rm "$IMAGE" info
# Verify every recorded documentation SHA-256
docker run --rm "$IMAGE" docs --verify
Use docs --list to see the topics available in a particular image. Topic
names follow the documentation actually present in its installation; for example,
the expanded dar_backup/doc/ collection first appears with dar-backup
1.1.11.
The stable filesystem location is /usr/share/doc/dar-backup/. It contains:
image/README.md β this image repository's exact build-context READMEREADME.md, the Markdown description embedded in package metadatadoc/, every file included under dar_backup/doc/ or dar_backup/docs/licenses/ and raw METADATAINDEX.md and the integrity/provenance record MANIFEST.json/usr/share/doc/dar-backup-image/README.md and /README.md link to the
embedded image operating guide for simple filesystem discovery. Use
docs image to print it and docs overview for the dar-backup overview.
The standalone executables dar-backup-image-docs and
dar-backup-image-info remain usable when the container entrypoint is
overridden. The OCI labels org.opencontainers.image.documentation,
org.dar-backup.documentation.command, and
org.dar-backup.documentation.path provide discovery without starting the
image.
The image contains man pages for dar and par2 which make the image self-documenting for all commands used to restore or backup.
dar-backup / dar / PAR2 environment with your archivesdar, Python tooling, or PAR2 requireddar-backup, dar-backup-image, dar and par2 documentation is included and easily discoverable by future users/etc/dar-backup/dar-backup.conf unless overriddenCurrent operation vs. long-term preservation
Use
:latestwhen you want the current tested and security-refreshed image.For disaster recovery years into the future, pin a version and save the image itself alongside your archives.
dar-backup in a Containerβ dar versionsβ dar-backup commandsβ
Long-term backups need more than durable data. They also need a practical way to run the software required to inspect, verify, repair, and restore that data.
A DAR archive is intentionally portable, and dar itself remains the essential restore tool. The container adds another layer of resilience by preserving a complete, known-working environment containing:
dardar-backupFor a backup intended to survive many years, preserve the image as data, not merely as a Docker Hub tag.
A typical workflow is:
# Pin a released image
VERSION=0.5.27
IMAGE=per2jensen/dar-backup:${VERSION}
# Pull the exact version
docker pull "$IMAGE"
# Save it as a portable compressed artifact
docker save "$IMAGE" | gzip > "dar-backup-image-${VERSION}.tar.gz"
Years later, on a machine with a compatible container runtime:
gunzip -c dar-backup-image-0.5.27.tar.gz | docker load
docker run --rm --entrypoint dar per2jensen/dar-backup:0.5.27 --version
The supplied scripts/save-dar-backup-image.shβ
automates the pull and docker save operation. It is intended for cron or a
systemd timer and saves a new archive when build history gains a higher-numbered
release or weekly refresh.
The current helper is an availability tool, not a complete provenance archiver.
It does not yet compare the pulled tag with the recorded digest, run Cosign,
or preserve the build-history record, SBOM, signature, and attestation beside
the image. Cosign material stored in the registry is not included by
docker save. The helper does create and subsequently validate a SHA-256 file
for each compressed archive, and it validates an existing archive before
reporting success. Verify the immutable digest and Cosign identity as described
below and save the relevant evidence beside the archive.
When creating an archive manually with the commands above, generate and verify its checksum yourself:
sha256sum "dar-backup-image-${VERSION}.tar.gz" \
> "dar-backup-image-${VERSION}.tar.gz.sha256"
sha256sum --check "dar-backup-image-${VERSION}.tar.gz.sha256"
Container images are architecture-specific. Record the image architecture with
docker image inspect --format '{{.Architecture}}' "$IMAGE" and ensure the
future recovery host can run it natively or through tested emulation.
The practical preservation model is therefore:
DAR archive slices
+
PAR2 recovery data
+
dar_manager catalogs
+
documentation
+
saved versioned dar-backup image
=
a self-contained recovery set
This does not mean Docker Hub should be treated as part of your disaster-recovery dependency chain. The opposite is the goal: save the image locally so recovery does not depend on Docker Hub, PyPI, Ubuntu repositories, the original host, or this GitHub repository still being available.
The signed image digest, SBOM, build history, and Rekor record provide provenance only when they are preserved and verified with the image; the locally saved image provides availability.
dar-backup in a ContainerCurious how it all works in practice?
Check out the step-by-step demoβ , which walks through:
.JPG only)All performed using docker run, no host installation required.
dar versionsStarting with dar-backup-image 0.5.15, dar (v2.7.18) is compiled from source rather than using Ubuntu 24.04βs older package.
The pinned dar release is compiled with the feature set verified by this
project, including zstd, lz4, Argon2, GPGME, and remote repository support.
The Dockerfileβ verifies the source tarball using Denis Corbinβs GPG key, checks all critical features, and only includes the built binary if everything passes.
To view the embedded dar version:
docker run -it --entrypoint /usr/local/bin/dar dar-backup:<tag> --version
Expected (abridged) output for tag 0.5.16, confirming core capabilities:
dar version 2.7.19, Copyright (C) 2002-2025 Denis Corbin
Using libdar 6.8.3 built with compilation time options:
gzip compression (libz) : YES
Strong encryption (libgcrypt): YES
Public key ciphers (gpgme) : YES
Large files support (> 2GB) : YES
Remote repository (libcurl) : YES (HTTPS, zstd, SSH, HTTP/2)
Weekly image refreshes (
:latest) are not listed here, see the full audit trail in build-history.jsonβ .
| Tag | dar-backup | dar | Release date | Git Revision | Docker Hub | Note |
|---|---|---|---|---|---|---|
| 1.0.0-rc1 | 1.1.11 | 2.7.21 | 2026-09-06 | 9a27ba88a11ae340c9ea95ec72e6271269c5ff2e | tag:1.0.0-rc1β | - |
| 0.9.1 | 1.1.11 | 2.7.21 | 2026-08-26 | 5576be82b9fedf44df6c9e3d0eb6b6c274ec5274 | tag:0.9.1β | - |
| 0.9.0 | 1.1.11 | 2.7.21 | 2026-08-16 | cfaadb1 | tag:0.9.0β | - |
| 0.5.28 | 1.1.10 | 2.7.21 | 2026-07-08 | c2b576e | tag:0.5.28β | - |
| 0.5.27 | 1.1.9 | 2.7.21 | 2026-07-06 | 1948e6c | tag:0.5.27β | - |
The table is generated from doc/build-history.json. Refresh it at any time
with python3 scripts/update_readme_releases.py, or verify it without writing
with python3 scripts/update_readme_releases.py --check.
Every image released to Docker Hub is produced by a fully automated GitHub Actions workflow, no manual docker push, no local machine involvement. The pipeline enforces a strict sequence of gates before any image becomes publicly available.
dar-backup:dev image is built using the repository's version pins. DAR is compiled from its GPG-verified source tarball; release images install the pinned dar-backup package from PyPI.dar-backup --version, the exact application revision, and the SHA-256 of /LICENSE before publication. The full pytest suite is not repeated against the relabeled image.:latest still identifies the previous known-good image.dar-backup --version output and OCI image-version label must match exactly.:latest; :latest is then pulled and required to resolve to the signed digest.:latest remains untouched.Manual releases and weekly image refreshes use the same tested publication
component and a shared concurrency lock, so their signing, rollback, remote
verification, :latest promotion, and always-run Docker credential cleanup
cannot drift apart or race.
Keyless signing means the project does not manage or store a long-lived signing private key in GitHub Secrets or on disk. Cosign generates an ephemeral key for the signing operation, and Fulcioβ issues a short-lived certificate bound to GitHub's OIDC identity for the workflow run.
Every signature is permanently recorded in Rekorβ , Sigstore's public, append-only transparency log. This means:
cosign verify per2jensen/dar-backup:<tag> \
--certificate-identity-regexp='^https://github\.com/per2jensen/dar-backup-image/\.github/workflows/(release|image-refresh)\.yml@refs/heads/main$' \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com"
A successful verification proves the image was signed on main by this
repository's manual-release or weekly-refresh workflow. Verification should use
the immutable digest recorded in doc/build-history.json when auditing a
specific publication.
cosign verify-attestation per2jensen/dar-backup:<tag> \
--type cyclonedx \
--certificate-identity-regexp='^https://github\.com/per2jensen/dar-backup-image/\.github/workflows/(release|image-refresh)\.yml@refs/heads/main$' \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
| jq '.payload | @base64d | fromjson | .predicate'
This retrieves and verifies the signed CycloneDX SBOM attached to the image, listing every package and library bundled inside.
Each release summary in the GitHub Actions tab includes a direct link to the Rekor entry for that release, for example:
https://search.sigstore.dev/?logIndex=1273042416
The entry records the signing certificate, the image digest that was signed, the GitHub workflow identity, the run URL, and the exact commit SHA, providing a complete, tamper-evident audit trail from source code to published image.
The -v flag that maps host directories into the container is the key decision that controls
how many backup definitions you can use, and which host paths are reachable at all.
In short:
/ β container /data read-only, the entire host tree is visible;
multiple definitions can target different subtrees, but the backup destination
and special filesystems can also reappear below /data. Use explicit exclusions./data read-only, only that directory
is visible inside the container./data read-only, multiple
definitions work without exposing the full host; this is the preferred
multi-source layout.See doc/dar-backup-mount-scenarios.mdβ for a full explanation with diagrams, worked examples, and a comparison table.
| Topic | Link |
|---|---|
dar-backup | dar-backup on GitHubβ |
dar-backup-image | dar-backup-imageβ |
Docker Hub repo | Docker Hubβ |
dar | Disk ARchiveβ |
dar-backup-image is licensed under GPL-3.0-or-later.
The complete license text is available in the repository LICENSE fileβ
and is embedded in every image at /LICENSE. Print it without installing or starting
dar-backup:
Copyright and licensing information is also recorded per file using SPDXβ and the REUSE specificationβ . Clonepulse files retain their MIT licence, while bundled upstream DAR source archives retain their upstream
Content type
Image
Digest
sha256:7e58bfaa2β¦
Size
72.9 MB
Last updated
2 days ago
docker pull per2jensen/dar-backup