Backup your Bitwarden/Vaultwarden vaults to encrypted json files https://github.com/mvfc/backvault
100K+
BackVault is a lightweight Dockerized service that periodically backs up your Bitwarden or Vaultwarden vaults into password-protected encrypted files. Itβs designed for hands-free, secure, and automated backups using the official Bitwarden CLI.
You can run BackVault directly using the published Docker image, no build required.
You can use either the GitHub Registry image (ghcr.io/mvfc/backvault) or the Docker Hub image (mvflc/backvault).
docker run -d \
--name backvault \
-e BW_SERVER="https://vault.yourdomain.com" \
-e BACKUP_ENCRYPTION_MODE="raw" \
-e BACKUP_INTERVAL_HOURS=12 \
-v /path/to/backup:/app/backups \
-v /path/to/db:/app/db \
-p 8080:8080 \
ghcr.io/mvfc/backvault:latest
π Important: The container uses the official Bitwarden CLI internally. Your credentials are only used to generate the export β they are never stored persistently and never sent anywhere else.
BackVault now includes a secure one-time web-based setup UI that replaces the need to pass sensitive credentials via environment variables. When you start the container for the first time, it will:
8080.Once setup is complete:
You can safely restart or update the container later without re-entering credentials, as long as the /app/db volume persists.
π§© Tip: You can mount the
/app/dbdirectory to your host if you want to persist encrypted credentials across container updates.
The new version of BackVault is built around principle of least privilege and container-isolated secrets:
UID 1000).BW_PASSWORD or BW_CLIENT_SECRET as environment variables.Together, these changes make BackVault one of the most secure self-hosted Bitwarden backup utilities available β suitable even for multi-user and shared-host environments.
Hereβs how to set it up with Docker Compose for easy management:
services:
backvault:
image: ghcr.io/mvfc/backvault:latest
container_name: backvault
restart: unless-stopped
environment:
BW_SERVER: "https://vault.yourdomain.com"
BACKUP_ENCRYPTION_MODE: "raw" # Use 'bitwarden' for the default format
BACKUP_INTERVAL_HOURS: 12
NODE_TLS_REJECT_UNAUTHORIZED: 0
volumes:
- ./backups:/app/backups
- ./db:/app/db
ports:
- "8080:8080"
Then run:
docker compose up -d
BackVault will automatically:
/app/backups (mounted to your host directory)| Variable | Description | Required | Example |
|---|---|---|---|
BW_SERVER | Bitwarden or Vaultwarden server URL | β | https://vault.example.com |
BACKUP_INTERVAL_HOURS | Alternative to cron expression (integer hours) | β | 12 |
BACKUP_ENCRYPTION_MODE | bitwarden (default) or raw for portable AES-256-GCM encryption. | β | raw |
RETAIN_DAYS | Days to keep backups. 7 by default. Set to 0 to disable cleanup. | β | 7 |
CRON_EXPRESSION | Cron string to schedule backups | β | 0 */12 * * * |
NODE_TLS_REJECT_UNAUTHORIZED | Set to 0 for self-signed certs | β | 0 |
BackVault supports two encryption modes, set by the BACKUP_ENCRYPTION_MODE environment variable. The decryption method depends on which mode was used to create the backup.
bitwarden (Default)This mode uses Bitwarden's native encrypted JSON format. It's secure but proprietary, meaning you must use the Bitwarden CLI to decrypt it.
How to Decrypt:
Install the official Bitwarden CLI: bitwarden.com/help/cli/
Config the CLI to point to your server with bw config server.
Log in using bw login.
Run the import command. This will decrypt the file and import it into your vault.
# This command decrypts the file and imports it into a vault.
bw import bitwardenjson /path/to/backup.enc
You will be prompted to enter your encryption password before the import can complete.
This method can be used to restore your vault into the same or a different Bitwarden account. The encryption is self-contained.
raw (Recommended for Portability)This mode exports the vault as raw JSON and then encrypts it in-memory using a standard, portable format: AES-256-GCM with a key derived using PBKDF2-SHA256.
The main advantage is that you do not need the Bitwarden CLI to decrypt your data, making it ideal for disaster recovery. You can use standard tools like Python or OpenSSL.
File Structure:
The resulting .enc file contains: [16-byte salt][12-byte nonce][encrypted data + 16-byte auth tag]
How to Decrypt (Python Script):
Here is a simple Python script to decrypt the file. You only need the cryptography library.
decrypt.py.pip install cryptography.python decrypt.py /path/to/backup.enc "YOUR_FILE_PASSWORD"# decrypt.py
import os
import sys
from getpass import getpass
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
from cryptography.exceptions import InvalidTag
SALT_SIZE = 16
KEY_SIZE = 32
PBKDF2_ITERATIONS = 600000
def decrypt_data(encrypted_data: bytes, password: str) -> bytes:
salt = encrypted_data[:SALT_SIZE]
nonce = encrypted_data[SALT_SIZE:SALT_SIZE+12]
ciphertext_with_tag = encrypted_data[SALT_SIZE+12:]
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), length=KEY_SIZE, salt=salt, iterations=PBKDF2_ITERATIONS)
key = kdf.derive(password.encode("utf-8"))
aesgcm = AESGCM(key)
return aesgcm.decrypt(nonce, ciphertext_with_tag, None)
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"Usage: python {sys.argv[0]} <encrypted_file> [password]")
sys.exit(1)
file_path = sys.argv[1]
password = sys.argv[2] if len(sys.argv) > 2 else getpass("Enter backup password: ")
try:
with open(file_path, "rb") as f:
encrypted_contents = f.read()
decrypted_json = decrypt_data(encrypted_contents, password)
print(decrypted_json.decode("utf-8"))
print("\nDecryption successful.", file=sys.stderr)
except InvalidTag:
print("Decryption failed: Invalid password or corrupted file.", file=sys.stderr)
except Exception as e:
print(f"An error occurred: {e}", file=sys.stderr)
restic or rclone to push backups to cloud storage.To update to the latest version:
docker pull ghcr.io/mvfc/backvault:latest
If using docker compose:
docker compose pull
docker compose up -d
This project is licensed under the AGPL-3.0 License. See LICENSE for details.
Pull requests and issue reports are welcome! Feel free to open a PR or discussion on GitHub.
BackVault β secure, automated, encrypted vault backups.
Content type
Image
Digest
sha256:62f691e4cβ¦
Size
422.5 MB
Last updated
3 days ago
docker pull mvflc/backvault