How to Self-Host Vaultwarden: Complete Guide to Installation, HTTPS, Security, and Remote Access
Vaultwarden is a lightweight, open-source reimplementation of the Bitwarden server written in Rust. It is fully compatible with all official Bitwarden clients (browser extensions, desktop apps, iOS, Android) and runs on hardware as modest as a Raspberry Pi using under 50 MB of RAM. This guide covers everything: what Vaultwarden is and how it compares to Bitwarden and 1Password, Docker installation, why HTTPS is mandatory and how to solve it without a domain using Localtonet, the correct way to generate the ADMIN_TOKEN with Argon2, how to disable open registration, connecting Bitwarden clients, a complete backup strategy, Fail2Ban brute-force protection, and a dedicated Raspberry Pi section.
What Is Vaultwarden?
Vaultwarden (formerly known as bitwarden_rs) is an unofficial, community-maintained alternative implementation of the Bitwarden server API, written in Rust. It was created by dani-garcia and is currently maintained by a small team of contributors. Vaultwarden is not affiliated with Bitwarden Inc., but one of its active maintainers is employed by Bitwarden and contributes to the project independently in their own time.
What makes Vaultwarden special is the combination of full Bitwarden client compatibility with dramatically lower resource usage. The official Bitwarden server requires 11 separate Docker containers and substantial RAM to run. Vaultwarden runs as a single container and uses under 50 MB of RAM at idle, making it practical to run on a Raspberry Pi alongside other services.
Vaultwarden is not an official Bitwarden product. Do not contact Bitwarden support for Vaultwarden issues. Report bugs and request help on the Vaultwarden forum or GitHub. Also note: if you lose your master password, your data is permanently unrecoverable. Vaultwarden uses the same client-side encryption model as Bitwarden; the server never has access to your plaintext passwords, which also means there is no password recovery mechanism.
Vaultwarden vs Bitwarden vs 1Password
| Feature | Vaultwarden (Self-Hosted) | Bitwarden (Official Self-Hosted) | Bitwarden Cloud | 1Password |
|---|---|---|---|---|
| Hosting | Your hardware only | Your hardware only | Bitwarden's servers | Cloud only (no self-host) |
| Cost | Free (infrastructure only) | Free community edition | Free (limited) / $10/year personal | $36/year personal |
| Docker containers required | 1 | 11+ | N/A | N/A |
| RAM usage | ~50 MB idle | ~2+ GB | N/A | N/A |
| Runs on Raspberry Pi | Yes (Pi 3/4/5) | Not practically | N/A | N/A |
| Client compatibility | All official Bitwarden clients | All official Bitwarden clients | All official Bitwarden clients | 1Password clients only |
| Premium features (TOTP, sharing, collections) | All included, free | Requires paid license for some | $10/year for premium | Included in subscription |
| Official support | Community only | Yes | Yes | Yes |
| Data privacy | 100% on your hardware | 100% on your hardware | Bitwarden's US servers | 1Password's servers |
| Encryption model | Client-side AES-256. Server never sees plaintext. | Same | Same | Client-side, proprietary |
Why HTTPS Is Mandatory for Vaultwarden
Vaultwarden uses the Web Crypto API in the browser to perform all encryption and decryption of vault data on the client side. The Web Crypto API is only available in secure contexts. A secure context means either http://localhost (same machine only) or any https:// URL. There is no workaround or configuration option to bypass this.
In practice this means: you cannot access your Vaultwarden instance from any other device using plain HTTP. If you try, the web vault UI will load but all cryptographic operations will silently fail. You must serve Vaultwarden over HTTPS for it to work from any device other than localhost.
There are three ways to get HTTPS for a self-hosted Vaultwarden:
- Own a domain + Let's Encrypt: Traditional approach. Requires a domain, a reverse proxy (Caddy or Nginx), and open ports 80/443 on your router. Does not work behind CGNAT.
- Self-signed certificate: Works but requires manually trusting the certificate on every device. Causes browser warnings and breaks most mobile apps.
- Localtonet tunnel (recommended for home use): Localtonet provides a public HTTPS URL instantly. No domain needed, no port forwarding, works behind CGNAT. This is the method this guide focuses on.
Requirements
| Component | Minimum | Notes |
|---|---|---|
| CPU | Any 64-bit | ARM64 or x86_64. Vaultwarden uses very little CPU. |
| RAM | 256 MB | Vaultwarden idles at ~50 MB. 512 MB total system RAM is fine for Pi Zero 2W+. |
| Storage | 1 GB | The vault database is tiny. Main storage is file attachments if enabled. |
| Docker | Docker 24+, Compose v2 | Single container, no Compose strictly required but recommended. |
| HTTPS | Mandatory | Web Crypto API requires a secure context. Use Localtonet tunnel. |
Installation: Docker Compose
Step 1: Install Docker
# Linux (Ubuntu, Debian, Raspberry Pi OS 64-bit):
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
# Log out and back in, then verify:
docker --version
docker compose version
Expected output:
Docker version 27.x.x, build xxxxxxx
Docker Compose version v2.x.x
Step 2: Generate the ADMIN_TOKEN (Argon2)
The ADMIN_TOKEN protects the Vaultwarden admin panel at /admin. Since Vaultwarden version 1.28.0, plain-text tokens trigger a security warning in the logs. The correct method is to generate an Argon2id hash using the Vaultwarden binary itself:
# Run a temporary Vaultwarden container just to generate the hash:
docker run --rm -it vaultwarden/server:latest /vaultwarden hash
You will be prompted to enter and confirm a password. Use a strong password (this is what you will type to log into the admin panel). Expected output:
Generate an Argon2id PHC string using the 'bitwarden' preset:
Password:
Confirm Password:
ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$SomeRandomSalt$SomeHashString'
Copy the hash string (everything between the single quotes, without the quotes themselves). You will use it in the next step.
This is the most common source of errors with Argon2 tokens. Docker Compose interpolates $ characters in environment values. The Argon2 hash contains multiple $ characters. When you paste the hash directly inside docker-compose.yml (not in a .env file), every $ must be doubled to $$ to prevent Docker Compose from treating them as variable references.
However, when you put the hash in a .env file and reference it in docker-compose.yml as ${ADMIN_TOKEN}, the .env file does NOT need escaping. Single $ characters work correctly in .env files.
Use a .env file (shown below) to avoid this problem entirely.
Step 3: Create project directory and .env file
mkdir ~/vaultwarden && cd ~/vaultwarden
Create the .env file. Paste your Argon2 hash as-is, with no escaping, no quotes:
cat > .env << 'ENVEOF'
# Replace the value below with your actual Argon2 hash (no quotes, no $$ escaping):
ADMIN_TOKEN=$argon2id$v=19$m=65540,t=3,p=4$YourSaltHere$YourHashHere
# Set to false after creating your account:
SIGNUPS_ALLOWED=true
# Will be set to your Localtonet public URL in a later step:
DOMAIN=https://localhost
# Timezone:
TZ=Europe/Istanbul
ENVEOF
Step 4: Create docker-compose.yml
cat > docker-compose.yml << 'EOF'
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
ports:
- "127.0.0.1:8080:80"
volumes:
- ./vw-data:/data
env_file: .env
environment:
- ADMIN_TOKEN=${ADMIN_TOKEN}
- SIGNUPS_ALLOWED=${SIGNUPS_ALLOWED}
- DOMAIN=${DOMAIN}
- TZ=${TZ}
- LOG_FILE=/data/vaultwarden.log
- LOG_LEVEL=warn
- EXTENDED_LOGGING=true
EOF
Notice that the port binding is 127.0.0.1:8080:80, not 0.0.0.0:8080:80. This means Vaultwarden only accepts connections from the local machine. External access goes through the Localtonet tunnel, which connects to localhost. This is more secure than binding to all interfaces.
Step 5: Start Vaultwarden
docker compose up -d
# Verify the container is running:
docker compose ps
Expected output:
NAME IMAGE STATUS
vaultwarden vaultwarden/server:latest Up 30 seconds
# Check startup logs for any errors:
docker compose logs vaultwarden
Expected log output (no errors):
[vaultwarden::config] Running on 0.0.0.0:80
[vaultwarden::api] Starting web server on 0.0.0.0:80
At this point Vaultwarden is running on http://localhost:8080. You can open it in a browser on the same machine to verify it loads. It will not work fully yet because HTTPS is required for the Web Crypto API. The next step adds HTTPS via Localtonet.
Setting Up HTTPS with Localtonet
Localtonet creates an encrypted outbound tunnel from your machine to a public HTTPS endpoint. Vaultwarden running on localhost:8080 becomes accessible at a public https:// URL. This satisfies the Web Crypto API secure context requirement, and the Bitwarden mobile apps and browser extensions can connect from any network. No port forwarding, no domain purchase, works behind CGNAT.
Install Localtonet
# Linux / Raspberry Pi OS:
curl -fsSL https://localtonet.com/install.sh | sh
# Verify:
localtonet --version
Authenticate with your AuthToken
Register at localtonet.com, go to Dashboard → My Tokens, copy your AuthToken:
localtonet --authtoken YOUR_TOKEN_HERE
Create an HTTP tunnel for port 8080
Go to localtonet.com/tunnel/http. Fill in:
- IP:
127.0.0.1 - Port:
8080 - Custom Subdomain (optional): e.g.
myvault
Click Create, then Start. Your public URL appears: e.g. https://myvault.localto.net
Update the DOMAIN variable in .env
Vaultwarden uses DOMAIN to generate correct URLs for invitations, 2FA setup emails, and other internal links. Update it with your public URL:
# Edit .env and change:
DOMAIN=https://myvault.localto.net
Restart Vaultwarden to apply:
docker compose restart vaultwarden
Run Localtonet as a service (always-on)
sudo localtonet --install-service --authtoken YOUR_TOKEN_HERE
sudo localtonet --start-service --authtoken YOUR_TOKEN_HERE
The tunnel now starts automatically on every reboot alongside Vaultwarden.
First Login and Critical Security Steps
Create your account
Open your public HTTPS URL (e.g. https://myvault.localto.net) in your browser. Click Create Account and register with your email and a strong master password. This is the password that encrypts your vault. Write it down and store it somewhere physically safe. There is absolutely no way to recover a lost master password.
Disable open registration immediately
After creating your account (and any other accounts for family or team members), disable open registration so no one else can create an account on your instance:
# Edit .env and change:
SIGNUPS_ALLOWED=false
# Restart:
docker compose restart vaultwarden
Alternatively, you can manage this from the admin panel. Navigate to https://myvault.localto.net/admin, enter the password you used to generate the Argon2 hash, go to General Settings, uncheck Allow new signups, and click Save.
This confuses many new users. The ADMIN_TOKEN environment variable contains the Argon2 hash of your password. But when you visit /admin in the browser, you type the original password you used when generating the hash, not the hash string itself. Vaultwarden verifies the entered password against the stored hash, just like any login system.
Enable Two-Factor Authentication
Log into your vault, go to Settings → Security → Two-step Login. Vaultwarden supports TOTP (authenticator apps like Aegis, Google Authenticator, Authy), email codes, and FIDO2/WebAuthn hardware keys. Enable at least TOTP. Scan the QR code with your authenticator app and confirm with a code before saving.
Invite additional users from the admin panel
With SIGNUPS_ALLOWED=false, new users cannot self-register. Instead, invite them from /admin: go to Users → Invite User, enter their email address, and they receive an invitation link. Invitations require SMTP email to be configured; alternatively, you can create accounts by temporarily setting SIGNUPS_ALLOWED=true, having them register, then setting it back to false.
Connecting Bitwarden Clients to Your Vaultwarden
Vaultwarden works with all official Bitwarden clients without modification. You just need to tell each client the server URL. Bitwarden clients default to the official Bitwarden cloud; you change this once during login setup and the client remembers it.
Browser Extension (Chrome, Firefox, Edge, Safari)
Install the official Bitwarden browser extension from your browser's extension store.
Open the extension. On the login screen, click the Region selector (shows "bitwarden.com" by default) and choose Self-hosted.
In the Server URL field, enter your Localtonet public URL: https://myvault.localto.net
Click Save, then log in with your email and master password.
iOS and Android App
Install the official Bitwarden app from the App Store or Google Play.
On the login screen, tap the Region selector and choose Self-hosted.
Enter your Localtonet public URL: https://myvault.localto.net
Tap Save, log in with your email and master password. Your vault syncs immediately.
Desktop App (Windows, macOS, Linux)
Open the Bitwarden desktop app. On the login screen, click the Region dropdown, select Self-hosted, enter your server URL, and save. The process is identical to the browser extension.
Raspberry Pi Installation
Vaultwarden is one of the best services to run on a Raspberry Pi. It is so lightweight that it runs comfortably even on a Pi Zero 2W (512 MB RAM). The Pi 4 and Pi 5 are ideal for running Vaultwarden alongside other services.
Vaultwarden's Docker image supports ARM64 (aarch64). Use the 64-bit version of Raspberry Pi OS from Raspberry Pi Imager. Verify with uname -m: it should return aarch64. The 32-bit OS works but the 64-bit image is better supported and performs better.
Install Docker on Raspberry Pi
sudo apt update && sudo apt upgrade -y
# Install Docker:
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker pi
# Log out and back in
# Verify:
docker --version
docker compose version
Install Vaultwarden on Raspberry Pi
The Docker Compose setup from the installation section above works on Raspberry Pi without any changes. The vaultwarden/server:latest image includes an ARM64 build and Docker automatically pulls the correct architecture.
mkdir ~/vaultwarden && cd ~/vaultwarden
# Create .env and docker-compose.yml as shown above
docker compose up -d
# Check resource usage on Pi:
docker stats vaultwarden --no-stream
Expected output (Pi 4, idle):
NAME CPU % MEM USAGE / LIMIT MEM %
vaultwarden 0.00% 48MiB / 3.7GiB 1.27%
Keep Vaultwarden always running on Pi
The restart: unless-stopped directive in docker-compose.yml already handles restarts on crash. To ensure it starts on boot, enable Docker to start at boot:
sudo systemctl enable docker
Docker Compose services with restart: unless-stopped start automatically when Docker starts. No additional configuration is needed.
Storing vault data on an external drive (Pi)
The vault database and attachments are stored in ./vw-data (the bind mount). On a Pi, this defaults to the SD card. For reliability, move it to a USB SSD:
# Mount USB SSD:
sudo mkdir -p /mnt/vault-data
sudo mount /dev/sda1 /mnt/vault-data
# Make permanent:
echo "UUID=$(sudo blkid -s UUID -o value /dev/sda1) /mnt/vault-data ext4 defaults,nofail 0 2" | sudo tee -a /etc/fstab
# Update the volume path in docker-compose.yml:
# Change: - ./vw-data:/data
# To: - /mnt/vault-data:/data
docker compose down && docker compose up -d
Backing Up Vaultwarden
Vaultwarden stores all data in the /data directory inside the container (mounted as ./vw-data on the host). This directory contains:
| File / Folder | Contains | Critical? |
|---|---|---|
db.sqlite3 | All vault data: passwords, notes, cards, identities, collections, organizations | Yes, most critical |
db.sqlite3-wal | SQLite write-ahead log (open transactions) | Yes, must back up with db.sqlite3 |
attachments/ | File attachments stored in vault items | Yes, if you use attachments |
sends/ | Bitwarden Send encrypted files | Yes, if you use Sends |
config.json | Settings saved via the admin panel (overrides env vars) | Yes |
vaultwarden.log | Log file | No |
rsa_key* | RSA keys used for JWT signing | Yes (losing these logs out all users) |
SQLite uses WAL (Write-Ahead Logging) mode by default. Doing a simple cp db.sqlite3 while Vaultwarden is running can produce a corrupt backup because the WAL file may contain uncommitted transactions. Always use the SQLite .backup command or the built-in Vaultwarden backup command, which both produce a consistent snapshot.
Backup script (runs without stopping Vaultwarden)
#!/bin/bash
# Save as ~/vaultwarden/backup.sh
# Add to cron: 0 2 * * * ~/vaultwarden/backup.sh
BACKUP_DIR=~/vaultwarden-backups/$(date +%F_%H%M)
mkdir -p "$BACKUP_DIR"
# 1. Create a consistent SQLite backup using the .backup command:
sqlite3 ~/vaultwarden/vw-data/db.sqlite3 \
".backup '$BACKUP_DIR/db.sqlite3'"
# 2. Back up attachments, sends, config, and RSA keys:
rsync -a ~/vaultwarden/vw-data/attachments/ "$BACKUP_DIR/attachments/" 2>/dev/null || true
rsync -a ~/vaultwarden/vw-data/sends/ "$BACKUP_DIR/sends/" 2>/dev/null || true
cp ~/vaultwarden/vw-data/config.json "$BACKUP_DIR/" 2>/dev/null || true
cp ~/vaultwarden/vw-data/rsa_key* "$BACKUP_DIR/" 2>/dev/null || true
# 3. Back up the .env file (contains ADMIN_TOKEN):
cp ~/vaultwarden/.env "$BACKUP_DIR/.env.backup"
echo "Backup complete: $BACKUP_DIR"
# 4. Keep only last 14 days of backups:
find ~/vaultwarden-backups -maxdepth 1 -type d -mtime +14 -exec rm -rf {} +
# Make executable and test:
chmod +x ~/vaultwarden/backup.sh
~/vaultwarden/backup.sh
# Add to cron (runs at 2 AM daily):
(crontab -l 2>/dev/null; echo "0 2 * * * ~/vaultwarden/backup.sh") | crontab -
Restore from backup
# Stop Vaultwarden first:
docker compose down
# Remove existing database files (including WAL):
rm ~/vaultwarden/vw-data/db.sqlite3*
# Copy the backup database:
cp ~/vaultwarden-backups/YYYY-MM-DD_HHMM/db.sqlite3 ~/vaultwarden/vw-data/db.sqlite3
# Restore attachments and other files:
rsync -a ~/vaultwarden-backups/YYYY-MM-DD_HHMM/attachments/ ~/vaultwarden/vw-data/attachments/
cp ~/vaultwarden-backups/YYYY-MM-DD_HHMM/config.json ~/vaultwarden/vw-data/
# Start Vaultwarden:
docker compose up -d
Fail2Ban: Protecting Against Brute-Force Attacks
Vaultwarden logs failed login attempts to /data/vaultwarden.log (when LOG_FILE and LOG_LEVEL=warn are set). Fail2Ban reads this log and bans IP addresses that make too many failed attempts. The Docker Compose setup below adds Fail2Ban as a sidecar container.
# Add to docker-compose.yml services section:
fail2ban:
image: crazymax/fail2ban:latest
container_name: fail2ban
restart: unless-stopped
network_mode: host
cap_add:
- NET_ADMIN
- NET_RAW
volumes:
- ./vw-data:/vaultwarden/data:ro
- ./fail2ban:/data
# Create Fail2Ban jail config:
mkdir -p ./fail2ban/jail.d
cat > ./fail2ban/jail.d/vaultwarden.local << 'EOF'
[vaultwarden]
enabled = true
port = 80,443,8080
filter = vaultwarden
logpath = /vaultwarden/data/vaultwarden.log
maxretry = 5
bantime = 14400
findtime = 14400
[vaultwarden-admin]
enabled = true
port = 80,443,8080
filter = vaultwarden-admin
logpath = /vaultwarden/data/vaultwarden.log
maxretry = 3
bantime = 14400
findtime = 14400
EOF
# Create Fail2Ban filters:
mkdir -p ./fail2ban/filter.d
cat > ./fail2ban/filter.d/vaultwarden.conf << 'EOF'
[Definition]
failregex = ^.*Username or password is incorrect\. Try again\. IP: .*$
^.*Failed to verify the CAPTCHA\. IP: .*$
ignoreregex =
EOF
cat > ./fail2ban/filter.d/vaultwarden-admin.conf << 'EOF'
[Definition]
failregex = ^.*Invalid admin token\. IP: .*$
ignoreregex =
EOF
docker compose up -d fail2ban
Updating Vaultwarden
Vaultwarden releases updates frequently. Updating is a two-command operation with Docker Compose:
cd ~/vaultwarden
# Pull the latest image:
docker compose pull vaultwarden
# Recreate the container with the new image:
docker compose up -d vaultwarden
# Confirm the new version:
docker exec vaultwarden /vaultwarden --version
Vaultwarden handles database migrations automatically on startup. No manual migration steps are required for most updates. Always run your backup script before pulling a new version:
~/vaultwarden/backup.sh && docker compose pull && docker compose up -d
Important Environment Variables Reference
| Variable | What It Does | Recommended Value |
|---|---|---|
ADMIN_TOKEN |
Argon2id hash of the admin panel password. Without this, the /admin panel is disabled entirely. | Argon2 hash from docker run --rm -it vaultwarden/server:latest /vaultwarden hash |
DOMAIN |
The public URL of your Vaultwarden instance. Used for invitation links, 2FA setup, and Bitwarden Send URLs. | https://myvault.localto.net |
SIGNUPS_ALLOWED |
Whether anyone can create an account. Set to false after creating your accounts. | false |
INVITATIONS_ALLOWED |
Whether org admins can invite users even when SIGNUPS_ALLOWED=false. | true |
LOG_FILE |
Path to log file inside the container. Required for Fail2Ban to work. | /data/vaultwarden.log |
LOG_LEVEL |
Log verbosity. warn logs failed logins. debug logs everything (verbose). |
warn |
SMTP_HOST |
SMTP server for sending invitation and 2FA emails. Optional but recommended. | Your email provider's SMTP server |
SMTP_FROM |
From address for outgoing emails. | vault@yourdomain.com |
SMTP_PORT |
SMTP port. 587 for STARTTLS, 465 for SSL/TLS. | 587 |
SMTP_SECURITY |
SMTP security type. | starttls |
SMTP_USERNAME |
SMTP authentication username. | Your email address or SMTP user |
SMTP_PASSWORD |
SMTP password. Use an app-specific password for Gmail. | Your SMTP password |
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Web vault loads but login fails silently | Accessing Vaultwarden over HTTP instead of HTTPS. Web Crypto API is unavailable. | Access via the Localtonet HTTPS URL. Never use http:// from a remote device. |
| "Invalid admin token" when logging into /admin | Entering the hash string instead of the password, or config.json has an old token overriding the env var | Enter the password you used when generating the hash, not the hash itself. If config.json exists in vw-data, open it and update admin_token there or delete the file and rely on env var alone. |
| "You are using a plain text ADMIN_TOKEN" warning in logs | Using a plain text token instead of Argon2 hash | Generate an Argon2 hash with docker run --rm -it vaultwarden/server:latest /vaultwarden hash and update ADMIN_TOKEN in .env. Restart container. |
| Bitwarden app says "An error has occurred" when connecting | Wrong server URL, or DOMAIN env var not set to HTTPS URL | Confirm DOMAIN in .env is set to your full Localtonet HTTPS URL including https://. Restart container. |
| Container exits immediately after start | Malformed ADMIN_TOKEN in docker-compose.yml (dollar signs not escaped) | Use a .env file for ADMIN_TOKEN instead of putting the hash directly in docker-compose.yml. In .env files, no dollar sign escaping is needed. |
| Vault does not sync on mobile after server URL change | App has cached the old server URL | Log out of the Bitwarden app completely, clear app data if needed, log back in and re-enter the new server URL during login. |
| File attachments not restoring after backup | Only database was restored, not the attachments/ folder | The attachments folder must be restored alongside the database. Both are in vw-data. Restore the entire vw-data directory from backup. |
Frequently Asked Questions
Is Vaultwarden safe to use for real passwords?
Vaultwarden uses the same client-side AES-256 encryption model as official Bitwarden. All encryption and decryption happens on the client device. Your Vaultwarden server stores only encrypted ciphertext and never has access to your plaintext passwords. The security of your vault therefore depends on: the strength of your master password, enabling two-factor authentication, keeping Vaultwarden updated, securing the server it runs on (strong admin token, Fail2Ban, HTTPS), and maintaining reliable backups. Vaultwarden has not undergone a formal third-party security audit, unlike official Bitwarden. For most personal and family use, it is considered secure by the community, but this is a factor to consider for high-stakes enterprise deployments.
What happens if I lose my Vaultwarden server or data?
If you have regular backups (database + attachments + rsa_key files), you can restore your Vaultwarden instance on a new machine and all vault data will be accessible. Your master password is not stored on the server, so backups do not need to be protected from that angle, though protecting the backup files from unauthorized access is still good practice. If you have no backup and lose the server, your passwords are gone permanently. Run the backup script daily with a cron job and test the restore process at least once before depending on it.
Can I migrate from Bitwarden cloud to Vaultwarden?
Yes. In the official Bitwarden web app or desktop app, go to Tools → Export Vault and export as an encrypted JSON file or plain-text JSON (use encrypted for security). In your new Vaultwarden instance, go to Tools → Import Data, select Bitwarden as the format, and import the file. All passwords, notes, cards, and identities transfer. File attachments must be re-uploaded manually as they are not included in vault exports. The entire migration typically takes under 15 minutes.
Do I need a domain name to run Vaultwarden?
No. With Localtonet, you get a public HTTPS URL without owning a domain. Localtonet provides a subdomain like https://myvault.localto.net which is a fully valid HTTPS URL. Vaultwarden and all Bitwarden clients work correctly with it. If you want a custom domain (e.g. vault.yourname.com), you can use Localtonet's custom domain feature with your own DNS settings, but it is not required.
What is the difference between ADMIN_TOKEN and the master password?
These are two completely separate credentials. The master password is your vault login password set when creating your account. It encrypts your vault data on the client. The ADMIN_TOKEN is the password for the Vaultwarden server administration panel at /admin. The admin panel lets you manage users, settings, and organizations at the server level. You set the admin password by generating an Argon2 hash with the vaultwarden hash command and storing the hash in the ADMIN_TOKEN environment variable. When you visit /admin, you enter the original password, not the hash.
Can Vaultwarden run on a Raspberry Pi Zero?
Raspberry Pi Zero 2W (which uses ARM Cortex-A53, ARMv8/64-bit compatible) can run Vaultwarden with the 64-bit Raspberry Pi OS Lite and Docker. The original Pi Zero (ARMv6) cannot run current Docker images for Vaultwarden. The Pi Zero 2W has 512 MB RAM, which is enough given that Vaultwarden idles at around 50 MB. It will be slow for initial setup but fine for low-traffic personal use. A Pi 4 or Pi 5 is strongly preferred for a smoother experience.
Give Your Self-Hosted Vaultwarden a Public HTTPS URL
Vaultwarden requires HTTPS to work from any device. Localtonet provides a public HTTPS URL instantly without a domain, without port forwarding, and without opening any ports on your router. Works behind CGNAT. Free to start.
Get Your HTTPS Tunnel Free →