Self-Hosting Vaultwarden: Zero Open Ports, Automated Backups, and Peace of Mind
If you have ever considered self-hosting a password manager, you have probably hit two immediate worries:
- “Is it safe to expose my most sensitive passwords to the internet?”
- “What happens if my server hardware crashes and I lose everything?”
These are completely valid concerns. Your password manager holds the keys to your entire digital life—you cannot afford downtime, vulnerabilities, or data loss.
The good news? With modern tools, you can build a resilient, production-grade password vault that requires zero open router ports, provides automatic HTTPS, and performs encrypted daily offsite backups to Google Drive. Best of all, you can spin up the entire stack in under 15 minutes.
Here is how to set up Vaultwarden on your homelab or VPS with total peace of mind.
Why This Stack?
Here is why this combination is a favorite among homelabbers:
- Vaultwarden: An ultra-lightweight, community-driven Rust rewrite of the official Bitwarden server backend. It uses a fraction of the RAM (often under 50 MB!) while remaining 100% compatible with all official Bitwarden apps, mobile clients, and browser extensions.
- Cloudflare Tunnel: Connects your container directly to Cloudflare’s global network via an outbound connection. You don’t need port forwarding, dynamic DNS, or firewall openings, and Cloudflare automatically handles SSL termination (mandatory for Bitwarden’s Web Crypto APIs).
- Automated Encrypted Backups via
vaultwarden-backup: Runs a scheduled cron job that locks your SQLite database, creates a password-protected ZIP archive, and syncs it straight to Google Drive using Rclone. If your server dies tomorrow, your encrypted vault is safe offsite. - Alpine Linux / LXC Container: Minimalist, featherweight, and rock-solid (though this setup works on any Docker-capable Linux host).
Architecture Overview
[Official Bitwarden Apps & Browsers]
│ (HTTPS)
▼
[Cloudflare Edge]
│
│ (Encrypted Outbound Tunnel - No open ports!)
▼
┌───────────────────────────────┐
│ Host (Alpine Linux / LXC) │
│ │
│ ┌───────────────────────┐ │
│ │ cloudflared tunnel │ │
│ └───────────┬───────────┘ │
│ │ (Internal) │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ vaultwarden │ │
│ └───────────┬───────────┘ │
│ │ (ro mount) │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ vaultwarden-backup │ │
│ └───────────┬───────────┘ │
└───────────────┼───────────────┘
│ (Encrypted Zip)
▼
[Google Drive]
Prerequisites
Before diving in, make sure you have:
- A machine running Docker & Docker Compose (e.g., an Alpine Linux LXC container, Ubuntu server, or VPS).
Note for Proxmox users: If you run Alpine in an unprivileged LXC container, ensure
nesting=1andkeyctl=1are enabled in the container options for Docker support. - A domain managed through Cloudflare (free tier works great).
- A Google account (for storing encrypted offsite backups).
Step 1: Create the Project Structure
Log into your server and create a dedicated directory for your stack:
mkdir -p /opt/vaultwarden/{vw-data,rclone-config/rclone}
cd /opt/vaultwarden
Here is what these folders are for:
vw-data/: Holds your persistent Vaultwarden database, configuration, and attachments.rclone-config/: Stores the Google Drive authentication tokens used by the backup container.
Step 2: Configure Google Drive Backups with Rclone
We will use Rclone to securely communicate with Google Drive. You do not need to install Rclone directly on your host—we can run it once inside the backup container to generate the credentials:
docker run --rm -it \
-v /opt/vaultwarden/rclone-config/rclone:/config/rclone/ \
ttionya/vaultwarden-backup:latest \
rclone config
Follow the interactive prompt:
- Type
nto create a new remote. - Enter the name:
gdrive. - Choose storage type: select
drive(Google Drive). - Leave
client_idandclient_secretblank (unless using your own Google API project). - Choose scope: option
1(Full access to all files). - When asked for auto-config, choose
nif you are on a headless server, and follow the browser authentication URL, or paste the verification code. - Confirm and save the configuration (
qto exit).
Finally, log into your Google Drive in your web browser and create a folder named VaultwardenBackups at the root (or whichever name you prefer).
Step 3: Configure Environment Variables
Create an .env file in /opt/vaultwarden:
nano .env
Add the following values:
# Cloudflare Tunnel token from the Zero Trust dashboard
TUNNEL_TOKEN=<YOUR_CLOUDFLARE_TUNNEL_TOKEN>
# The public domain you will use for your vault
VAULT_DOMAIN=vault.yourdomain.com
How to get your
TUNNEL_TOKEN: In the Cloudflare Zero Trust Dashboard, navigate to Networks > Tunnels > Create a tunnel. Choose Cloudflared, give it a name, and copy the tunnel token provided in the installation instructions.
Step 4: Define the Docker Compose Stack
Create docker-compose.yml:
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: always
environment:
- DOMAIN=https://${VAULT_DOMAIN}
- WEBSOCKET_ENABLED=true
- SIGNUPS_ALLOWED=true # Set to false after creating your account!
volumes:
- ./vw-data:/data
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
restart: always
command: tunnel --no-autoupdate run --token ${TUNNEL_TOKEN}
vaultwarden-backup:
image: ttionya/vaultwarden-backup:latest
container_name: vaultwarden-backup
restart: always
environment:
- RCLONE_REMOTE_NAME=gdrive
- RCLONE_REMOTE_DIR=VaultwardenBackups
- CRON=0 3 * * * # Runs daily at 03:00 UTC
- ZIP_ENABLE=TRUE
- ZIP_PASSWORD=<YOUR_STRONG_BACKUP_PASSPHRASE>
- BACKUP_KEEP_DAYS=30
- TIMEZONE=UTC
volumes:
- ./vw-data:/bitwarden/data/:ro
- ./rclone-config/rclone:/config/rclone/
Why this configuration shines:
- Zero Host Ports Exposed: Notice there is no
ports:section! Vaultwarden communicates withcloudflaredover the private Docker bridge network. - Read-Only Backup Mount:
vw-datais mounted to the backup container as:ro, preventing any possibility of the backup tool accidentally modifying your vault. - Encrypted Archives:
ZIP_PASSWORDensures your Google Drive backup is AES-encrypted before it ever leaves your machine. Store this passphrase in a safe physical notebook or emergency recovery kit!
Step 5: Route Traffic in Cloudflare
In your Cloudflare Zero Trust dashboard under your Tunnel configuration:
- Go to the Public Hostname tab.
- Click Add a public hostname.
- Set your subdomain and domain (e.g.
vaultandyourdomain.com). - Under Service:
- Type:
HTTP - URL:
vaultwarden:80(since both containers share the same Docker network, Cloudflare routes directly using the container name!).
- Type:
- Save the hostname.
Step 6: Launch and Verify
Start up your entire stack with one command:
docker compose up -d
Check the status of your containers:
docker compose ps
Test the Backup Pipeline Right Away
Don’t wait until 3:00 AM to discover if your backups work! Trigger a manual run right now:
docker exec -it vaultwarden-backup /app/backup.sh
Inspect the logs:
docker logs vaultwarden-backup
You should see confirmation that the database was safely backed up, zipped with encryption, and uploaded to your VaultwardenBackups folder in Google Drive. Open Google Drive to see your brand-new encrypted backup archive sitting safely in the cloud!
Post-Installation Best Practices
To ensure long-term security, take two minutes to complete these finishing touches:
- Create Your Master Account: Visit
https://vault.yourdomain.com, register your account, and set a long, memorable Master Password. - Lock Down Public Signups: Once your account is set up, edit
docker-compose.ymland set:
Then apply changes with- SIGNUPS_ALLOWED=falsedocker compose up -d. This blocks unauthorized visitors from registering accounts on your server. - Turn on 2FA: In the Vaultwarden web interface, enable WebAuthn/FIDO2 (hardware security keys) or an authenticator app for secondary verification.
- Emergency Sheet: Write down your Master Password and your backup
ZIP_PASSWORDon physical paper and store it in a secure location (such as a fireproof safe).
Conclusion
Taking ownership of your digital identity does not require a massive rack of servers or complex networking gymnastics. In just a few minutes, you have built:
- A private, lightning-fast password manager.
- A rock-solid zero-trust tunnel with SSL and no open ports.
- An automated, encrypted offsite backup strategy that protects you against hardware failure.
Now open up the official Bitwarden apps on your phone and desktop, point the server URL to https://vault.yourdomain.com, and enjoy true password sovereignty!