· VaultwardenDockerCloudflareSelf-Hosted

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:

  1. “Is it safe to expose my most sensitive passwords to the internet?”
  2. “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:

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:

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:

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:

  1. Type n to create a new remote.
  2. Enter the name: gdrive.
  3. Choose storage type: select drive (Google Drive).
  4. Leave client_id and client_secret blank (unless using your own Google API project).
  5. Choose scope: option 1 (Full access to all files).
  6. When asked for auto-config, choose n if you are on a headless server, and follow the browser authentication URL, or paste the verification code.
  7. Confirm and save the configuration (q to 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:

Step 5: Route Traffic in Cloudflare

In your Cloudflare Zero Trust dashboard under your Tunnel configuration:

  1. Go to the Public Hostname tab.
  2. Click Add a public hostname.
  3. Set your subdomain and domain (e.g. vault and yourdomain.com).
  4. Under Service:
    • Type: HTTP
    • URL: vaultwarden:80 (since both containers share the same Docker network, Cloudflare routes directly using the container name!).
  5. 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:

  1. Create Your Master Account: Visit https://vault.yourdomain.com, register your account, and set a long, memorable Master Password.
  2. Lock Down Public Signups: Once your account is set up, edit docker-compose.yml and set:
    - SIGNUPS_ALLOWED=false
    Then apply changes with docker compose up -d. This blocks unauthorized visitors from registering accounts on your server.
  3. Turn on 2FA: In the Vaultwarden web interface, enable WebAuthn/FIDO2 (hardware security keys) or an authenticator app for secondary verification.
  4. Emergency Sheet: Write down your Master Password and your backup ZIP_PASSWORD on 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:

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!