Skip to content

About

VolumeVault is a self-hosted Laravel application for managing Docker volume and host path backups with safe restores powered by offen/docker-volume-backup.

Topics

Resources

Security policy

Stars

102 stars

Watchers

0 watching

Forks

Latest commit

 

History

270 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VolumeVault

VolumeVault

tests Container image Latest release PHP License

VolumeVault is a self-hosted Laravel application for managing Docker volume and host path backups with safe restores through offen/docker-volume-backup.

It provides a clear web UI for scheduled backups, grouped backups with a single aggregated notification, stack-level volume coverage, restore runs, encrypted destinations, notifications, proactive alerts, run history, onboarding, and API-driven automation.

VolumeVault dashboard preview VolumeVault backup jobs preview

Get Started

Generate an application key first:

docker run --rm ghcr.io/darkdragon14/volumevault:latest php artisan key:generate --show

Create a docker-compose.yml file and paste the generated key in APP_KEY:

services:
  volumevault:
    image: ghcr.io/darkdragon14/volumevault:latest
    ports:
      - "8080:8080"
    volumes:
      - volumevault_data:/app/storage
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      APP_KEY: base64:paste-generated-key-here
    restart: unless-stopped

volumes:
  volumevault_data:

Start VolumeVault:

docker compose up -d

Open http://localhost:8080 and create the first administrator account from the onboarding screen.

The container listens on port 8080; change the host side of the mapping, for example 9090:8080, if you want to expose VolumeVault on another port.

The single container runs nginx, PHP-FPM, database migrations, queue worker, and scheduler.

If a MySQL upgrade failed in 2026_09_22_072732_add_destination_operations_to_agent_operations with error 1059 (index name too long), update to the fixed code and rerun php artisan migrate --force in the application environment. The migration resumes after partially committed columns or foreign keys without deleting existing rows. Do not use migrate:fresh for recovery; it deletes data. Existing SQLite installations require no schema changes and retain rollback compatibility.

To connect through a Docker TCP endpoint, such as a socket proxy in front of the same Docker engine, use the standalone TCP file: VOLUMEVAULT_DOCKER_HOST=tcp://docker-proxy.example.internal:2375 docker compose -f docker-compose.tcp.yml up -d. The separate interpolation variable configures the container without redirecting the host Docker CLI, and the TCP file does not mount /var/run/docker.sock. The base file is fixed to the local Unix socket so an ambient DOCKER_HOST cannot accidentally combine proxy mode with unrestricted socket access. The endpoint applies to the entire VolumeVault instance and must be reachable from both VolumeVault and the temporary Offen backup containers. If the proxy hostname only resolves on a user-defined Docker network, set VOLUMEVAULT_DOCKER_NETWORK to that network's engine-visible name so Offen joins it. This does not add support for managing a Docker engine on another host. Docker TCP access is root-equivalent; keep it on a trusted private network and see the installation and security documentation before enabling it.

Defaults are built into the application for a production SQLite setup. Add environment variables only when you need to override them, for example APP_URL, APP_TIMEZONE, or SMTP settings.

You can also use env_file: .env for overrides, but do not reuse a development .env in production without review. Values such as APP_ENV=local or APP_DEBUG=true override the safe production defaults.

Host path backup jobs and local backup destinations are restricted by VOLUMEVAULT_HOST_PATH_ALLOWLIST, a comma-separated list of allowed Docker host path prefixes such as /srv,/mnt/data. This is fail-closed: when the variable is empty, host path sources and local destinations are refused entirely. Configure the prefixes you intend to back up to/from; paths outside them are rejected both when saved and again at run time. VolumeVault canonicalizes every path visible in its own filesystem, regardless of Docker transport, so resolvable symlink escapes are refused. Paths unavailable to VolumeVault receive lexical-only validation and must be protected from untrusted symlink replacement.

Backup destinations on a private IP (NAS, self-hosted S3/MinIO, LAN SFTP)

The requests VolumeVault makes to a backup destination on your behalf are guarded against SSRF, and this is deny-by-default: a destination host that resolves to a private, loopback or link-local address (including the cloud metadata endpoint 169.254.169.254) is refused. In practice this only matters when your destination sits on a private IP — a cloud destination reached by a public URL (AWS S3, Backblaze, Dropbox, …) is never affected and needs no configuration.

The trigger is the range of the resolved IP, not whether you typed an IP or a hostname. A public IP — whether written directly (http://203.0.113.10:9000) or reached through a hostname — is never blocked; that is by design, because the point of SSRF protection is to stop the server being used to reach internal resources an attacker could not otherwise touch (a public address is something they could already request themselves). Conversely a hostname is blocked when it resolves to a private address (e.g. an internal DNS name nas.home.lan → 192.168.1.x).

What this changes for a destination on a private IP, before you allow its range:

  • ✅ Scheduled backups still run — the upload is done by the backup container, which is not guarded, so the archive still lands on your NAS.
  • ⚠️ The archive size is not detected (the run is still marked successful).
  • ❌ Restore is blocked (listing + download) — this is the one that matters: a backup you cannot restore is useless.
  • ❌ The "Test destination" button and the storage-quota alert are blocked.

The fix is a single line: list the CIDR range(s) your destinations live on in VOLUMEVAULT_SSRF_ALLOWED_IPS (comma-separated), after which everything works normally while 169.254.169.254 and friends stay blocked:

# e.g. a NAS on your home LAN
VOLUMEVAULT_SSRF_ALLOWED_IPS=192.168.1.0/24

The host is resolved just before connecting, so a determined attacker controlling DNS could still rebind it afterwards — accepted here because every guarded action is admin-gated. Notification channels (Gotify, Ntfy, SMTP, …) are not guarded: they are blind, admin-configured, and commonly self-hosted on the LAN.

Backup retention

retention_count keeps the newest N archives belonging to a backup job on its destination. After a successful regular backup, VolumeVault lists the actual archives and deletes only the oldest excess files. Failed backups and pre-restore safety backups do not trigger count retention.

New archives carry a stable per-job prefix and a unique run ID, including when a custom filename template is used. Safety backups use a separate prefix. Both count and day retention are handled by VolumeVault and apply only to regular archives in the job namespace; if both limits are set, an archive exceeding either limit is eligible for deletion, except the newly uploaded archive. Archives from other jobs, unrelated files and older archives without this prefix are preserved. Existing files are not renamed; clean up legacy archives manually if needed.

Destination credentials must permit both listing and deletion, and private destinations must be allowed by VOLUMEVAULT_SSRF_ALLOWED_IPS. Update remote agents before using count retention. Check the backup run logs for cleanup failures: a successful upload does not guarantee that destination cleanup succeeded.

Serving over HTTPS

When you serve VolumeVault over HTTPS (directly or behind a TLS-terminating reverse proxy), set SESSION_SECURE_COOKIE=true so the session cookie is only sent over HTTPS. Leave it off for plain-HTTP or LAN-only access — a Secure cookie is never sent over plain HTTP, so enabling it without TLS breaks login. Behind a reverse proxy, this works once TRUSTED_PROXIES is set and the proxy forwards X-Forwarded-Proto: https (see the docs for the full reverse-proxy setup).

Keep your APP_KEY safe: it is required to decrypt destinations, notifications, two-factor secrets, and installation saves.

Deployment roles and agents

The default VOLUMEVAULT_MODE=hybrid keeps the existing local Docker executor. Set VOLUMEVAULT_MODE=orchestrator to run the central application without a Docker socket or remote Docker endpoint; docker-compose.orchestrator.yml provides a standalone deployment for this mode. Local jobs and history remain stored, but local execution is disabled. Drain local work through maintenance before changing modes.

Agents use the dedicated volumevault-agent PHP CLI image. The Docker hosts page shows local/central/agent roles, software and protocol compatibility, maintenance state, and a manual update guide. Keep each agent's existing /app/storage volume and configuration when replacing its container; a normal update does not require enrollment again. See docs/_tabs/installation.md for activation, image targets, compatibility and update procedures.

Compatible agents execute standalone backups and restores. Shared network destinations support restoring an archive from host A into a new volume on host B. Distributed groups, remote Docker-label reconciliation and relay of archives stored only on another host remain under development.

Documentation

The full documentation is published with GitHub Pages and built from the docs directory.

Credits

VolumeVault relies on offen/docker-volume-backup for the actual Docker volume backup engine and destination support.

Huge thanks to Offen and the maintainers of offen/docker-volume-backup for their work.

Contributing

All contributions are welcome.

About

VolumeVault is a self-hosted Laravel application for managing Docker volume and host path backups with safe restores powered by offen/docker-volume-backup.

Topics

Resources

Security policy

Stars

102 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages