How-toCybersecurity12 min read
How to Self-Host Bitwarden in 2026 (Step-by-Step on a Hostinger VPS)
Self-hosting Bitwarden puts your entire password vault on infrastructure you control, with zero monthly vendor fees. This is the exact Vaultwarden + Docker + Caddy setup we use to host our own family vault on a $5/month Hostinger VPS — TLS, admin panel, backups, and client config included.
Omer YLD
Founder & Editor-in-Chief
12 min · 2,400 words
Photo: Technerdo
By the end of this guide, you will have a fully self-hosted Bitwarden-compatible password vault running on your own VPS, with a real TLS certificate, a hardened firewall, and an automated backup schedule. The whole walkthrough takes about 45 minutes on a fresh server, costs roughly $5 per month in infrastructure, and gives you the same end-to-end encrypted experience as hosted Bitwarden with none of the subscription fees.
This is exactly the setup we run for our family vault: Vaultwarden (a lean open-source Rust implementation of the Bitwarden server API) plus Docker Compose, fronted by Caddy for automatic HTTPS, on a Hostinger VPS. Every official Bitwarden client works with it unchanged.
If you're still deciding whether self-hosting makes sense, our Bitwarden vs 1Password comparison covers the broader tradeoff. Once you've decided you want your vault on your own hardware, this is the fastest reliable path to get there.
What You'll Need
Before you start, gather the following:
- A VPS with at least 1 GB of RAM. We use a Hostinger VPS — the smallest tier is comfortable for a family vault and costs roughly $5/month. Any provider with root SSH access works; pick whoever you already trust.
- A domain name you control. Vaultwarden works over a plain IP, but TLS (and therefore most Bitwarden clients) needs a real domain. A subdomain like
vault.yourdomain.comis ideal. - Ability to edit DNS records for that domain.
- An SSH client (the Terminal on macOS/Linux; OpenSSH or Windows Terminal on Windows).
- Docker and Docker Compose. We install these during the walkthrough.
- About 45 minutes of uninterrupted time.
Total cost: the VPS ($5/month) and the domain ($12/year) are the only paid line items. Vaultwarden, Docker, Caddy, and every client app are free.
Choose Your Server: Vaultwarden Over Official Bitwarden
This is the first real decision. Both options are legitimate; they target different use cases.
Vaultwarden is a community-built Rust reimplementation of the Bitwarden server API. It speaks the same protocol as the official server, works with every official Bitwarden client, and runs in roughly 100 MB of RAM. The codebase is open source (GPLv3) and exceptionally well-maintained. For personal, family, or small-team use this is the right choice — lighter, simpler to deploy, and functionally complete.
Official Bitwarden Unified (the 2023+ simplified deployment) works for self-hosted installs too. It runs .NET plus a SQL database and wants 2 GB of RAM minimum, but it supports features Vaultwarden doesn't — native SSO, SCIM, formal paid support. Pick this if you run a real business on it and need those specific features.
For everything else, use Vaultwarden. The rest of this guide uses Vaultwarden; every step translates to the official server with minor Docker image swaps if you go that route.
Provision the VPS
Log into your Hostinger VPS dashboard and spin up a new VPS with a clean Ubuntu 24.04 LTS image. Note the IPv4 address and the root password (or SSH key you set during provisioning).
SSH in as root:
ssh root@your.vps.ip
Create a non-root user with sudo access and disable root SSH. This is baseline hygiene on any server:
adduser bw
usermod -aG sudo bw
rsync --archive --chown=bw:bw ~/.ssh /home/bw
Edit /etc/ssh/sshd_config, set PermitRootLogin no and PasswordAuthentication no, then systemctl restart ssh. Reconnect as bw using your key. If anything goes wrong with SSH config, use your VPS provider's console access to fix it before closing your original session — never lock yourself out.
Update packages and install a basic firewall:
sudo apt update && sudo apt upgrade -y
sudo apt install -y ufw
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable
Your server now accepts SSH, HTTP, and HTTPS — nothing else.
Install Docker and Docker Compose
Vaultwarden is distributed as an OCI container. Install Docker Engine using the official convenience script:
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
Log out and back in for the group change to take effect, then confirm:
docker --version
docker compose version
You should see Docker 27.x+ and Compose v2.x. Both ship with modern Docker installs.
Point Your Domain at the VPS
In your DNS provider's dashboard, create an A record for vault.yourdomain.com pointing at your VPS's IPv4 address. TTL 300 seconds is fine for the initial setup; you can raise it later.
Verify propagation from your laptop:
dig +short vault.yourdomain.com
You should see your VPS's IP. If it's empty, wait 2–5 minutes and try again. DNS changes usually propagate quickly with short TTLs.
Create the Vaultwarden Stack
On the VPS, create a working directory and the Compose file:
mkdir -p ~/vaultwarden && cd ~/vaultwarden
nano docker-compose.yml
Paste this docker-compose.yml — replace vault.yourdomain.com and the admin token with your own values:
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
DOMAIN: "https://vault.yourdomain.com"
SIGNUPS_ALLOWED: "false"
ADMIN_TOKEN: "REPLACE_WITH_A_LONG_RANDOM_STRING"
WEBSOCKET_ENABLED: "true"
volumes:
- ./vw-data:/data
caddy:
image: caddy:2
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
volumes:
caddy_data:
caddy_config:
Generate a strong admin token:
openssl rand -base64 48
Copy that value into the ADMIN_TOKEN environment variable in your Compose file.
Now create a Caddyfile in the same directory:
vault.yourdomain.com {
reverse_proxy vaultwarden:80
}
That's the entire reverse-proxy configuration. Caddy will handle Let's Encrypt certificate issuance and renewal automatically.
Start the Stack
From ~/vaultwarden:
docker compose up -d
Check the logs:
docker compose logs -f caddy
You should see Caddy acquiring a TLS certificate for your domain (this takes about 30 seconds). When the logs settle, open https://vault.yourdomain.com in a browser. You should see the Bitwarden login screen with a valid HTTPS lock icon.
Create Your Admin Account
Because SIGNUPS_ALLOWED is set to false, you need to either flip it temporarily to create your first account, or use the admin panel to invite yourself.
The cleaner option: browse to https://vault.yourdomain.com/admin, authenticate with the ADMIN_TOKEN you generated, and click Invite User to send yourself an invitation at your email address. Once you've registered via the invite link, leave signups disabled.
If you don't have SMTP configured yet (we cover that below), the simpler path is:
- Edit
docker-compose.ymland temporarily setSIGNUPS_ALLOWED: "true" docker compose up -dto reload- Register your account in the browser
- Set
SIGNUPS_ALLOWED: "false"again docker compose up -d
Lock the front door as soon as you're in. Open signups on a public-facing vault are a serious mistake.
Configure SMTP for Invites and Password Reset (Optional)
For a family or team vault, you'll want email working. Add these environment variables to the vaultwarden service in your Compose file:
SMTP_HOST: "smtp.your-provider.com"
SMTP_FROM: "vault@yourdomain.com"
SMTP_PORT: "587"
SMTP_SECURITY: "starttls"
SMTP_USERNAME: "vault@yourdomain.com"
SMTP_PASSWORD: "your-smtp-password"
Mailgun, SendGrid, and Postmark all have free tiers that more than cover vault email volume. docker compose up -d again to reload.
Point Your Bitwarden Clients at Your Vault
In the Bitwarden browser extension (or desktop, mobile, or CLI), log out of any existing session. On the login screen, look for the server URL or self-hosted option — usually a gear icon near the top. Enter https://vault.yourdomain.com as the server URL.
Log in with the account you created. Your vault is now end-to-end encrypted, stored on your own server, and the client interface is identical to hosted Bitwarden. Import your existing passwords from a CSV export of whatever vault you were using before.
Set Up Automated Backups
A password vault without backups is a single disk failure away from disaster. The Vaultwarden data directory (./vw-data on the host) is everything — database, attachments, icons, config. Back it up daily.
Create a simple backup script at /home/bw/backup-vault.sh:
#!/bin/bash
set -e
DATE=$(date +%Y-%m-%d)
cd /home/bw/vaultwarden
docker compose exec -T vaultwarden sqlite3 /data/db.sqlite3 ".backup '/data/db-backup-$DATE.sqlite3'"
tar czf /home/bw/backups/vault-$DATE.tar.gz -C /home/bw/vaultwarden vw-data
find /home/bw/backups -name "vault-*.tar.gz" -mtime +14 -delete
Make it executable and add a nightly cron entry:
chmod +x ~/backup-vault.sh
mkdir -p ~/backups
crontab -e
Add the line:
30 3 * * * /home/bw/backup-vault.sh >> /home/bw/backups/backup.log 2>&1
That runs at 03:30 every night and keeps 14 days of snapshots locally. For true disaster recovery, push those tarballs to offsite object storage. Restic plus a Backblaze B2 bucket costs cents per month and gives you encrypted offsite backups with incremental snapshots.
Troubleshooting Common Issues
Caddy can't acquire a certificate. Check that your domain's A record actually points at the VPS IP (dig +short vault.yourdomain.com from the VPS itself) and that UFW allows port 80. Let's Encrypt needs port 80 for the HTTP-01 challenge even if your final traffic is all HTTPS.
Bitwarden clients say "invalid server URL." Make sure you entered the full https://vault.yourdomain.com, including the scheme. Trailing slashes sometimes matter — try with and without.
Admin panel returns 404. ADMIN_TOKEN must be set in the environment. If you started the container without it, the admin panel is disabled entirely. Stop the stack, fix the Compose file, and docker compose up -d again.
Vaultwarden container keeps restarting. Run docker compose logs vaultwarden and read the last 50 lines. The most common cause is a malformed environment variable (especially quotes inside the ADMIN_TOKEN). Regenerate the token with openssl rand -hex 48 to avoid special characters.
Email isn't sending. Check docker compose logs vaultwarden | grep -i smtp. Authentication errors mean the username/password is wrong; connection errors mean your SMTP provider is blocking the VPS IP (some providers block datacenter IPs by default — Mailgun and SendGrid don't).
Is Self-Hosted Bitwarden Actually More Secure Than Hosted?
Not automatically. Self-hosting moves trust from Bitwarden's infrastructure team to you — and Bitwarden's infrastructure team is very, very good at security. You gain meaningful control (your encrypted vault never touches a third-party cloud), and you take on meaningful responsibility (patching, backups, firewall management). For a technical user who treats server hygiene seriously, self-hosted Vaultwarden on a hardened VPS is at least as secure as hosted Bitwarden. For a user who won't update their server for six months, hosted is safer.
What to Do Next
Now that you have a working self-hosted vault:
- Set up two-factor authentication on your master account. Bitwarden supports TOTP, hardware keys, and Duo. A hardware key like a Yubikey is the strongest option and works with every Bitwarden client.
- Migrate every device to the self-hosted server — browser extensions, phones, tablets. The faster you complete migration, the less chance you'll accidentally save a password to the old account.
- Consider self-hosting other services on the same VPS. If you're already running a VPS, self-hosted AI agents and home labs are natural next projects. A single Hostinger VPS can comfortably host Vaultwarden plus several other small services.
Self-hosting a password manager is one of the clearest wins in the self-hosted software category: the feature parity with the hosted service is near-complete, the operational burden is low (one VPS, one container, nightly backups), and the cost savings compound. A $60/year VPS replaces $35/year of Bitwarden Premium — and more meaningfully, it replaces the need to trust anyone else's infrastructure with your entire digital life.
Was this piece worth your five minutes?
Join the conversation — sign in to leave a comment and engage with other readers.
Loading comments...



