VaultSync
Configure once, forget forever. Automated Bitwarden vault backups with multi-remote cloud storage support. Set up once and enjoy hands-free daily backups to multiple cloud services simultaneously (S3, Google Drive, Dropbox, OneDrive, Cloudflare R2, and 40+ others). Supports both official Bitwarden and self-hosted servers.
π Quick Start (TL;DR)
1. Generate Rclone Config
# If you have this repo cloned:
./generate-rclone-base64.sh
# Interactive mode (create new config):
./generate-rclone-base64.sh --interactive
# Test config and save to file:
./generate-rclone-base64.sh --test --output my-config.txt
# Or manually create base64 from existing rclone config:
base64 -w 0 < ~/.config/rclone/rclone.conf
2. Minimal Configuration
Create a .env file with these 5 required variables:
cat > .env << EOF
BW_CLIENTID=your_bitwarden_client_id
BW_CLIENTSECRET=your_bitwarden_client_secret
BW_PASSWORD=your_bitwarden_master_password
ENCRYPTION_PASSWORD=your_strong_encryption_password
RCLONE_CONFIG_BASE64=your_base64_encoded_rclone_config
EOF
Optional: Organization Export Support
To also backup organization vaults, add these optional variables:
# Enable organization exports
EXPORT_ORGANIZATIONS=true
# Optional: list organization IDs to export (comma-separated, no spaces)
# If omitted, all accessible organizations are auto-discovered and exported
# Get org IDs manually with: bw list organizations --session $BW_SESSION
BW_ORGANIZATION_IDS=12345678-1234-1234-1234-123456789012,87654321-4321-4321-4321-210987654321
π Backup Format Compatibility:
- Personal-only backups (default): Uses standard Bitwarden export format
- Organization backups: Uses consolidated format when organizations are exported
- Restore script: Automatically detects and handles both formats
3. Run Backup
β‘ Fastest (No cloning required):
docker run --rm --env-file .env --pull always \
-e BITWARDENCLI_APPDATA_DIR=/tmp/bw_appdata \
nikhilbadyal/bitwarden-backup:latest
Or with Docker Compose:
git clone https://github.com/nikhilbadyal/bitwarden-backup.git
cd bitwarden-backup
# Copy your .env file here
docker-compose up --build --no-cache
# Added --no-cache to ensure latest image is always pulled.
Or with scripts:
./setup-rclone.sh && ./scripts/backup.sh
That's it! Your vault will be backed up to all configured remotes with encryption and compression.
π₯οΈ Want a Web UI? See the Management Interface section below for the complete web dashboard setup!
π Management Interface
This project includes both a modern web UI and REST API for managing your Bitwarden backups through an intuitive interface or programmatic access.
Quick Setup
π₯οΈ Web UI + API (Recommended):
# Start everything (UI + API + Redis + Nginx)
docker-compose -f docker-compose.full.yml up -d --build --no-cache
# Added --build --no-cache to ensure latest image is always pulled and rebuilt.
# Access the complete application
# - Web UI: http://localhost:80
# - API Docs: http://localhost:80/api/v1/docs
π API Only:
# Run the API with Docker
./run-api.sh
# Access the API
# - API Root: http://localhost:5050/
# - Documentation: http://localhost:5050/api/v1/docs
For detailed API setup instructions, Docker configuration, and usage examples, see:
π API.md - Complete API Setup Guide
The API provides endpoints for:
- π System health and monitoring
- π Backup file management and listing
- βοΈ Remote storage provider management
- π Advanced search and filtering capabilities
π₯οΈ Web UI Dashboard
This project includes a modern React-based web interface for managing your Bitwarden backups through an intuitive dashboard.
β¨ UI Features
- π Real-time System Health - Monitor API status, Redis connectivity, and Rclone availability
- βοΈ Remote Management - View and manage all configured cloud storage remotes
- π Backup Browser - Browse backup history with detailed metadata and logs
- π§ Rclone Config Tool - Convert and manage rclone configurations through the web interface
- π Secure Authentication - Token-based authentication with session management
- π± Responsive Design - Works on desktop, tablet, and mobile devices
π Quick UI Setup
Option 1: Full Stack (Recommended)
# Start everything (API + UI + Redis + Nginx)
docker-compose -f docker-compose.full.yml up -d
# Access the complete application
# - Web UI: http://localhost:80
# - API: http://localhost:80/api (proxied through Nginx)
Option 2: Manual Development Setup
# 1. Start the API backend
uvicorn api.main:app --host 0.0.0.0 --port 5050
# 2. In another terminal, start the UI
cd ui
npm install
npm start
# Access:
# - UI: http://localhost:3000
# - API: http://localhost:5050
Option 3: Docker Compose (Separate Services)
# Start API only
docker-compose -f docker-compose.api.yml up -d --build --no-cache
# Added --build --no-cache to ensure latest image is always pulled and rebuilt.
# Start UI only (in another terminal)
docker-compose -f docker-compose.ui.yml up -d --build --no-cache
# Added --build --no-cache to ensure latest image is always pulled and rebuilt.
# Access:
# - UI: http://localhost:3000
# - API: http://localhost:5050
π§ UI Configuration
The UI requires these environment variables for proper API connectivity:
| Variable | Description | Default | Docker Example |
|---|---|---|---|
VITE_API_BASE_URL |
API backend URL | http://localhost:5050 |
/api (with Nginx proxy) |
For development:
# In ui/.env file
VITE_API_BASE_URL=http://localhost:5050
For Docker with Nginx (recommended): The full Docker Compose setup automatically configures Nginx to:
- Serve the UI on port 80
- Proxy
/api/*requests to the backend - Handle CORS and routing properly
π¨ UI Development
The web interface is built with modern technologies:
- Frontend: React 19 + Vite
- UI Framework: Material-UI (MUI) v7
- Routing: React Router v7
- Build Tool: Vite (fast HMR and builds)
- Styling: Emotion + MUI theming
Development Commands:
cd ui
# Install dependencies
npm install
# Start development server (with hot reload)
npm start # or npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
# Lint and format code
npm run lint
npm run format
π Authentication
The UI uses token-based authentication:
- First Visit: You'll be redirected to the login page
- Enter API Token: Use the same
API_TOKENfrom your.envfile - Persistent Session: Token is stored in localStorage for convenience
- Logout: Click the logout button to clear the session
π± UI Screenshots & Features
System Health Dashboard:
- Real-time component status (Redis, Rclone)
- System uptime and version information
- One-click cache clearing
- Color-coded health indicators
Remote Storage Management:
- View all configured rclone remotes
- Test remote connectivity
- Storage usage and configuration details
Backup Browser:
- Chronological backup listing
- Detailed backup metadata (size, date, remote)
- Download and restoration options
- Search and filtering capabilities
Rclone Configuration:
- Web-based config converter
- Base64 encoding/decoding
- Configuration validation
π UI Development Notes
Full Disclosure: The web interface was "vibe coded" due to limited frontend expertise - it's fully functional but could use some design polish! π
Contributing: If you're a frontend developer and want to contribute design improvements, we'd be incredibly grateful! The codebase is contribution-friendly and uses modern React patterns.
Known Limitations:
- Basic responsive design (works but could be enhanced)
- Minimal animations and transitions
π Detailed Documentation
What This Does
This repository provides a "configure once, forget forever" solution for Bitwarden vault backups:
setup-rclone.sh: Configures rclone from a base64-encoded configuration to support ANY rclone-compatible storage servicebackup.sh: Performs automated backup, validates, compresses, encrypts, and uploads to ALL configured remotes simultaneouslygenerate-rclone-base64.sh: Helper script to generate base64-encoded rclone configurationsrestore-backup.sh: Decrypt and restore backup files back to plain JSON format
Prerequisites
- A Bitwarden account with API access enabled (works with both official Bitwarden and self-hosted servers)
- Docker installed (recommended) OR
bw,jq,gzip,openssl,rcloneCLI tools installed - Access to one or more cloud storage services with rclone support
Alternative Installation Methods
π§ Full Setup (Clone Repository):
git clone https://github.com/nikhilbadyal/bitwarden-backup.git
cd bitwarden-backup
# Generate rclone config
./generate-rclone-base64.sh
# Create .env file (copy from env.example)
cp env.example .env
# Edit .env with your values
# Run backup
./setup-rclone.sh && ./scripts/backup.sh
π§ Configuration
Required Environment Variables
| Variable | Description | Example |
|---|---|---|
BW_CLIENTID |
Your Bitwarden API Client ID | user.1234567890abcdef |
BW_CLIENTSECRET |
Your Bitwarden API Client Secret | abcdef1234567890 |
BW_PASSWORD |
Your Bitwarden Master Password | MySecretPassword123! |
ENCRYPTION_PASSWORD |
Strong password for backup encryption | BackupEncryption456! |
RCLONE_CONFIG_BASE64 |
Base64-encoded rclone configuration | W215LXMzXQp0eXBlID0gczMK... |
API Configuration (Required for API service)
| Variable | Description | Example |
|---|---|---|
API_TOKEN |
Authentication token for API access | your_secure_api_token |
REDIS_URL |
Redis connection URL for caching | redis://localhost:6379/0 |
BACKUP_PATH |
Remote path/bucket for storing backups | bitwarden-backup |
API_ALLOW_BACKUP_DECRYPTION |
Enables sensitive download/restore operations | false |
API_ALLOWED_HOSTS |
Trusted host allow-list (comma-separated) | localhost,127.0.0.1,api.example.com |
API_CORS_ORIGINS |
Explicit CORS origins (comma-separated) | http://localhost,http://localhost:3000 |
API_CORS_ALLOW_CREDENTIALS |
CORS credential support (true/false) |
true |
API_CORS_ALLOW_METHODS |
Explicit CORS methods (comma-separated) | GET,POST,PUT,DELETE,OPTIONS |
API_CORS_ALLOW_HEADERS |
Explicit CORS request headers (comma-separated) | Authorization,Content-Type,Accept |
API_CORS_EXPOSE_HEADERS |
CORS response headers exposed to browser (comma-separated) | X-Request-ID,X-Response-Time,X-API-Version |
API_STREAM_TOKEN_TTL_SECONDS |
Short-lived SSE stream token TTL in seconds | 120 |
Self-Hosted Bitwarden Support
This backup tool fully supports self-hosted Bitwarden servers! Configure your custom server using these optional environment variables:
| Variable | Description | Example |
|---|---|---|
BW_SERVER |
Primary server URL (recommended approach) | https://bitwarden.example.com |
BW_WEB_VAULT |
Custom web vault URL (advanced) | https://vault.example.com |
BW_API |
Custom API URL (advanced) | https://api.example.com |
BW_IDENTITY |
Custom identity URL (advanced) | https://id.example.com |
BW_ICONS |
Custom icons service URL (advanced) | https://icons.example.com |
BW_NOTIFICATIONS |
Custom notifications URL (advanced) | https://notify.example.com |
BW_EVENTS |
Custom events URL (advanced) | https://events.example.com |
BW_KEY_CONNECTOR |
Key Connector URL (for organizations) | https://keycon.example.com |
Quick Examples:
# For most self-hosted installations, just set BW_SERVER:
BW_SERVER="https://vault.mycompany.com"
# For Bitwarden EU cloud:
BW_SERVER="https://vault.bitwarden.eu"
# For complex custom setups (rarely needed):
BW_WEB_VAULT="https://vault.example.com"
BW_API="https://api.example.com"
BW_IDENTITY="https://identity.example.com"
Important Notes:
- Leave these variables empty or unset to use the official Bitwarden service
BW_SERVERis the recommended approach for most self-hosted installations- Individual service URLs (
BW_API,BW_IDENTITY, etc.) overrideBW_SERVERif both are set - All existing backup functionality works identically with self-hosted servers
Export Configuration Variables
| Variable | Description | Default | Example |
|---|---|---|---|
EXPORT_PERSONAL |
Export personal vault | true |
true or false |
EXPORT_ORGANIZATIONS |
Export organization vaults | false |
true or false |
BW_ORGANIZATION_IDS |
Optional org IDs to export; empty means auto-discover all accessible orgs | None | 12345678-...,87654321-... |
EXPORT_ORGANIZATIONS_FAIL_FAST |
Fail immediately when any org export fails (true) or continue with partial success (false) |
false |
true or false |
Format Details:
- When
EXPORT_ORGANIZATIONS=false(default): Uses standard Bitwarden export format - When
EXPORT_ORGANIZATIONS=true: Uses consolidated format withpersonalandorganizationssections - When
EXPORT_ORGANIZATIONS_FAIL_FAST=false(default): Organization export failures are logged and remaining orgs continue - Restore script automatically detects format and provides extraction options
Optional Variables (Advanced)
Click to expand optional configuration
| Variable | Description | Default |
|---|---|---|
BACKUP_DIR |
Temporary directory for backup files | /tmp/bw_backup |
BACKUP_PATH |
Remote path/bucket for storing backups | bitwarden-backup |
MIN_BACKUP_SIZE |
Minimum backup size in bytes | 1024 |
COMPRESSION_LEVEL |
Gzip compression level (1-9) | 9 |
RETENTION_COUNT |
Number of backups to keep per remote | 240 |
BW_UNLOCK_RETRIES |
Number of vault unlock attempts | 3 |
BW_UNLOCK_RETRY_DELAY |
Seconds to wait between retry attempts | 5 |
PBKDF2_ITERATIONS |
PBKDF2 iterations for encryption | 600000 |
BITWARDEN_SYNC_TIMEOUT |
Bitwarden sync timeout in seconds | 60 |
PARALLEL_THRESHOLD |
Min remotes needed for parallel processing | 3 |
MAX_PARALLEL_JOBS |
Maximum parallel jobs for pruning | 4 |
APPRISE_URLS |
Notification URLs (space-separated) | None |
BW_SERVER |
Self-hosted Bitwarden server URL | None |
BW_WEB_VAULT |
Custom web vault URL (advanced) | None |
BW_API |
Custom API URL (advanced) | None |
BW_IDENTITY |
Custom identity URL (advanced) | None |
BW_ICONS |
Custom icons service URL (advanced) | None |
BW_NOTIFICATIONS |
Custom notifications URL (advanced) | None |
BW_EVENTS |
Custom events URL (advanced) | None |
BW_KEY_CONNECTOR |
Key Connector URL (for organizations) | None |
Important Notes:
BACKUP_PATH: For S3-compatible services, this becomes the bucket name. For other services, this is the folder path where backups are stored.MIN_BACKUP_SIZE: Backups smaller than this are considered invalid and the script will exit with an error.PBKDF2_ITERATIONS: Changes only affect new backups. Restore script automatically detects iteration count for backward compatibility.- All scripts automatically load variables from
.envfile if it exists in the project root.
π What You Get (Features)
Backup Features:
- Multi-Remote Support: Backup to multiple cloud services simultaneously
- Strong Encryption: AES-256-CBC encryption with PBKDF2 (configurable, default 600,000 iterations) using your password
- Zero-Disk Security: Uses secure pipe-based processing - unencrypted vault data never touches disk
- Smart Change Detection: Only uploads when vault actually changes (SHA256 comparison)
- Detailed Notifications: Per-remote status in final notifications (success/failed/up-to-date)
- Automatic Retries: Handles network issues and API rate limiting for Bitwarden unlock
- Secure Cleanup: Logs out of Bitwarden and cleans temporary files
- Cross-platform: Supports Linux and macOS (different SHA256 utilities)
Restore Features:
- Multi-Source Restore: Decrypt local files or download from any remote
- Backup Browsing: List and browse backups across all storage services
- Verification Pipeline: Multi-stage validation (decryption β decompression β JSON validation)
ποΈ Detailed Documentation
Supported Cloud Storage Services
This backup solution supports ALL rclone-compatible storage services, including:
Object Storage:
- Amazon S3, Google Cloud Storage, Azure Blob Storage
- Cloudflare R2, Backblaze B2, Wasabi, MinIO
- IBM Cloud Object Storage, Oracle Cloud Storage
Consumer Cloud Storage:
- Google Drive, Dropbox, OneDrive, Box
- pCloud, Mega, Yandex Disk, Mail.ru Cloud
Enterprise Storage:
- SFTP, FTP, WebDAV, HTTP
- Swift (OpenStack), Ceph, QingStor
And many more! See the rclone documentation for the complete list.
Example Multi-Remote Setup
Your rclone configuration can include multiple remotes:
[aws-s3]
type = s3
provider = AWS
access_key_id = AKIAIOSFODNN7EXAMPLE
secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
region = us-east-1
[google-drive]
type = drive
client_id = 123456789.apps.googleusercontent.com
client_secret = abcdefghijklmnopqrstuvwx
token = {"access_token":"ya29.a0AfH6SMC..."}
[cloudflare-r2]
type = s3
provider = Cloudflare
access_key_id = your_r2_access_key
secret_access_key = your_r2_secret_key
endpoint = https://abc123.r2.cloudflarestorage.com
[dropbox-backup]
type = dropbox
token = {"access_token":"sl.B0abcdefghijklmnop..."}
The backup script will automatically:
- Detect all 4 remotes
- Upload your backup to ALL of them
- Maintain separate retention policies for each
- Track changes independently per remote
Usage Examples
Click to expand usage examples
Manual Backup (Scripts):
./setup-rclone.sh && ./scripts/backup.sh
Automated with Cron:
# Daily backup at 3:00 AM
0 3 * * * /path/to/bitwarden-backup/setup-rclone.sh && /path/to/bitwarden-backup/scripts/backup.sh >> /var/log/bitwarden_backup.log 2>&1
Docker Compose:
docker-compose up --build
Automated Docker Compose with Cron:
For automated backups using Docker Compose with cron scheduling, you have several options:
Add this to your host system's crontab:
# Daily backup at 3:00 AM using Docker Compose
0 3 * * * cd /path/to/bitwarden-backup && docker-compose up --build --force-recreate >> /var/log/bitwarden_backup.log 2>&1
# Weekly backup (Sundays at 2:00 AM)
0 2 * * 0 cd /path/to/bitwarden-backup && docker-compose up --build --force-recreate >> /var/log/bitwarden_backup.log 2>&1
# Multiple daily backups (every 6 hours)
0 */6 * * * cd /path/to/bitwarden-backup && docker-compose up --build --force-recreate >> /var/log/bitwarden_backup.log 2>&1
Cron Schedule Examples:
# Every day at 3:00 AM
0 3 * * *
# Every 12 hours (noon and midnight)
0 */12 * * *
# Every Monday at 2:00 AM
0 2 * * 1
# Every 1st day of the month at 1:00 AM
0 1 1 * *
# Every 15 minutes (for testing)
*/15 * * * *
# Multiple times per day (6 AM, 2 PM, 10 PM)
0 6,14,22 * * *
GitHub Actions Automation:
- Fork this repository
- Add your environment variables as a repository secret named
BITWARDEN_BACKUP_ENV - Automatic daily backups run at 2:00 AM UTC with free GitHub infrastructure
- Includes pre-commit checks (shellcheck) and log artifact storage
π Backup Restoration
The restore-backup.sh script allows you to decrypt and restore your encrypted backups back to plain JSON format.
Quick Restore Examples
# Decrypt a local backup file
./restore-backup.sh bw_backup_20241218123456.json.gz.enc
# Download and decrypt latest backup from S3 remote
./restore-backup.sh -r s3-remote
# List all available backups from all configured remotes
./restore-backup.sh -l
# Decrypt with custom output filename
./restore-backup.sh -f backup.enc -o my_vault.json
Restore Options
| Option | Description | Example |
|---|---|---|
-f, --file |
Decrypt local backup file | --file backup.enc |
-r, --remote |
Download & decrypt from remote | --remote s3-backup |
-o, --output |
Custom output filename | --output vault.json |
-l, --list |
List backups from all remotes | --list |
--list-remote |
List backups from specific remote | --list-remote gdrive |
--download-only |
Download without decrypting | --download-only |
Restoration Process
- π Validation - Checks file existence and encryption password
- π Decryption - Decrypts using AES-256-CBC with your password
- π¦ Decompression - Extracts gzip compressed data
- β JSON Validation - Ensures valid Bitwarden vault format
- πΎ Secure Save - Saves with secure file permissions (600)
- π§Ή Cleanup - Removes temporary files
Security Notes
- Restored JSON files contain unencrypted vault data - handle with care
- Files are created with secure permissions (owner read/write only)
- Temporary files are automatically cleaned up
- Delete restored files when no longer needed
- The same
ENCRYPTION_PASSWORDfrom backups is required
Advanced Features
Click to expand advanced features
Detailed Backup Features:
- Multi-Remote Support: Backup to multiple cloud storage services simultaneously (S3, Google Drive, Dropbox, OneDrive, Cloudflare R2, and 40+ others supported by rclone)
- Base64 Configuration: Accepts rclone config as base64 to avoid typing errors and enable easy deployment
- Isolated Configuration: Uses project-specific rclone config to avoid interfering with your global rclone setup
- Multi-Stage Validation: JSON validation, size checks, compression verification, and encryption testing
- Encryption Verification: Tests decryption and validates gzip format before upload
- Intelligent Change Detection: SHA256 hashing to avoid unnecessary uploads when vault hasn't changed
- Independent Retention Management: Per-remote retention policies based on configurable count
- Optional Apprise Notifications: Success and failure notifications
- Automatic Retry Logic: Handles transient network issues and API rate limiting for Bitwarden vault unlock
- Robust Error Handling: Individual remote failures don't stop the entire process
- Secure Cleanup: Logs out of Bitwarden and unsets sensitive environment variables
Detailed Restore Features:
- Multi-Source Restore: Decrypt local files or download directly from any configured remote
- Backup Browsing: List and browse available backups across all your cloud storage services
- Verification Pipeline: Multi-stage validation (decryption β decompression β JSON validation)
- Secure Processing: Temporary files with secure permissions and automatic cleanup
- Flexible Output: Custom output file names and locations
- Download-Only Mode: Download encrypted backups without decrypting (for manual processing)
Logging and Monitoring
Exit Codes
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Missing required environment variable |
2 |
Missing required dependency |
3 |
Backup directory issue |
4 |
Bitwarden login failed |
5 |
Bitwarden vault unlock failed |
6 |
Bitwarden data export failed |
7 |
Invalid backup file |
8 |
Compression or encryption failed |
99 |
Unexpected error during upload |
Notifications
Configure Apprise for notifications:
# Multiple notification services
APPRISE_URLS="mailto://[email protected] tgram://bot_token/chat_id discord://webhook_id/webhook_token"
Enhanced Notification Details:
The final notification now includes detailed per-remote status:
Success Notification Example:
Bitwarden backup script completed successfully. New backup uploaded: bw_backup_20241218123456.json.gz.enc.
π Remote Status:
β
aws-s3: Success
β
google-drive: Up to date
β dropbox-backup: Failed
β
cloudflare-r2: Success
π Summary: π€ 2 uploaded, β
1 up-to-date, β 1 failed
No Changes Notification Example:
Bitwarden backup script completed successfully. No changes detected, no new backup uploaded.
π Remote Status:
β
aws-s3: Up to date
β
google-drive: Up to date
β
cloudflare-r2: Up to date
Failure Notification Example:
Bitwarden backup script failed with exit code 8.
Reason: Compression or encryption failed. Check ENCRYPTION_PASSWORD.
β οΈ Remote Status at time of failure:
β
aws-s3: Success
β google-drive: Failed
βΈοΈ dropbox-backup: Not processed
Security Considerations
.envFile: Contains sensitive credentials. Set permissions tochmod 600 .env.- Backup Directory: Set secure permissions
chmod 700on backup directory. - Encryption Password: Store securely and separately from backups. Losing this password means losing access to your backups.
- Rclone Configuration: Contains cloud storage credentials. The base64 encoding is for convenience, not security.
- Multi-Remote Security: Each remote should have appropriate access controls and encryption.
Migration from R2-Only Version
If you're upgrading from the R2-only version:
- Keep your existing
.env- the new version is backward compatible - Generate rclone config: Use
./generate-rclone-base64.shto createRCLONE_CONFIG_BASE64 - Add the new variable to your
.envfile - Optional: Remove old R2-specific variables (they're ignored now)
- Run the backup - it will work with your existing R2 setup plus any new remotes
Troubleshooting
Common Issues
"RCLONE_CONFIG_BASE64 contains invalid base64 data" (Docker Hub image only):
There's a known issue with the Docker Hub image having stricter base64 validation than local builds. If your base64 works with local Docker Compose but fails with the Docker Hub image:
Workaround 1: Use local build instead
git clone https://github.com/nikhilbadyal/bitwarden-backup.git
cd bitwarden-backup
# Copy your .env file here
docker-compose up --build
Workaround 2: Regenerate base64 (may help)
base64 -w 0 < ~/.config/rclone/rclone.conf | tr -d '\n'
This issue is being investigated - the local build is currently more reliable.
No remotes found:
- Ensure
RCLONE_CONFIG_BASE64is properly set - Test your config:
./generate-rclone-base64.sh --test
Upload failures:
- Check remote credentials and permissions
- Verify network connectivity
- Review rclone configuration syntax
Permission errors:
- Ensure scripts are executable:
chmod +x *.sh scripts/*.sh - Check backup directory permissions
Bitwarden unlock failures:
The script includes automatic retry logic for vault unlock failures. If you're experiencing frequent unlock issues:
- Increase retry attempts: Set
BW_UNLOCK_RETRIES=5(default: 3) - Increase retry delay: Set
BW_UNLOCK_RETRY_DELAY=10(default: 5 seconds) - Check network connectivity to Bitwarden servers
- Verify your master password is correct in the
BW_PASSWORDvariable - Check for API rate limiting if running frequent backups
π Universal Architecture Support:
The Docker image is built for 2 main architectures and works universally:
- β linux/amd64 (Intel/AMD 64-bit: Most desktops, servers, cloud instances)
- β linux/arm64 (ARM 64-bit: Apple Silicon, Raspberry Pi 4/5, AWS Graviton)
Manual Installation (without Docker):
If running scripts directly on any system, install Bitwarden CLI via npm:
# Install Node.js and npm
sudo apt update && sudo apt install -y nodejs npm
# Install Bitwarden CLI globally
sudo npm install -g @bitwarden/cli
# Verify installation
bw --version
Read-only filesystem errors with Bitwarden CLI:
If you see errors like EROFS: read-only file system, open '/home/backupuser/.config/Bitwarden CLI/data.json':
This happens when the Docker container runs with a read-only filesystem but Bitwarden CLI needs to write configuration files. The Docker Compose file already handles this, but for manual Docker runs, add:
docker run --rm --env-file .env -e BITWARDENCLI_APPDATA_DIR=/tmp/bw_appdata nikhilbadyal/bitwarden-backup:latest
Using outdated Docker images:
Docker may use cached local images instead of pulling the latest from Docker Hub. To ensure you're running the most recent version:
# Option 1: Use --pull always flag (recommended)
docker run --rm --env-file .env -e BITWARDENCLI_APPDATA_DIR=/tmp/bw_appdata --pull always nikhilbadyal/bitwarden-backup:latest
# Option 2: Manually pull first, then run
docker pull nikhilbadyal/bitwarden-backup:latest
docker run --rm --env-file .env -e BITWARDENCLI_APPDATA_DIR=/tmp/bw_appdata nikhilbadyal/bitwarden-backup:latest
Note: docker-compose automatically handles this with pull_policy: always in the compose file.
Getting Help
- Check logs: Review script output for specific error messages
- Test rclone: Use
rclone ls remote:to test connectivity - Validate config: Use the
--testflag with the helper script - Check dependencies: Ensure all required tools are installed
Contributing
Contributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.
License
This project is open source. Please check the license file for details.