Bitwarden Self-Hosted Deployment
Notes on running the official Bitwarden server on your own infrastructure. Covers installation, configuration, updates, and backup.
Overview
Bitwarden sells a self-hosted option that keeps all vault data on your own servers. It’s the heavier counterpart to Vaultwarden — same compatible client apps, but more moving parts, more RAM, and SSO/SCIM on the paid tier. If you want a lightweight setup for personal or small-team use, Vaultwarden is usually the better call. Bitwarden proper is the one to reach for when you need the enterprise features, the compliance paperwork, or full control over the MS SQL database underneath.
The trade-off is real: you now own patching, backups, TLS, SMTP, and everything else. If you’re not ready for that responsibility, the hosted version is still the right answer.
System Requirements
Minimum Requirements
- CPU: 2 cores
- RAM: 4 GB
- Storage: 25 GB
- OS: Ubuntu 20.04+ LTS, Debian 10+, CentOS/RHEL 8+
- Docker: 20.10.x or later
- Docker Compose: 1.29.x or later
Recommended Requirements
- CPU: 4 cores
- RAM: 8 GB
- Storage: 50 GB SSD
- OS: Ubuntu 22.04 LTS (EOL: April 2027)
- Dedicated server or VM (not shared hosting)
Network Requirements
- Inbound: HTTPS (443)
- Outbound: Internet access for license validation (can be proxied)
- DNS: Resolvable hostname
- SSL Certificate: Valid certificate (Let’s Encrypt or commercial)
Installation
Prerequisites
Install Docker:
# Ubuntu/Debian
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER Install Docker Compose:
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose Obtain Installation ID and Key
- Visit: https://bitwarden.com/host/
- Enter email address
- Receive Installation ID and Installation Key via email
- Save these securely (required for installation)
Download and Run Installer
Create Bitwarden user:
sudo adduser bitwarden
sudo usermod -aG docker bitwarden
su - bitwarden Download installer:
curl -Lso bitwarden.sh "https://func.bitwarden.com/api/dl/?app=self-host&platform=linux" && chmod +x bitwarden.sh Run installation:
./bitwarden.sh install Installation Prompts
The installer will ask:
- Domain name:
vault.example.com - Let’s Encrypt certificate: Yes/No
- If Yes: Enter email for Let’s Encrypt notifications
- If No: Provide your own SSL certificate
- Database name:
vault(default, can customize) - Installation ID: From email
- Installation Key: From email
Configuration
Main Configuration File
Location: ./bwdata/config.yml
Key settings:
# Domain configuration
url: https://vault.example.com
domain: vault.example.com
# SSL/TLS
https_port: 443
http_port: 80
# Database
database:
type: mssql # or postgres
name: vault
username: bitwarden
# Password generated during install
# SMTP (for email)
mail:
replyToEmail: no-reply@example.com
smtp:
host: smtp.example.com
port: 587
ssl: false
startTls: true
username: bitwarden@example.com
# Password in environment variables
# Admin panel
adminSettings:
admins: admin@example.com Environment Variables
Location: ./bwdata/env/global.override.env
Common overrides:
# Admin email
globalSettings__mail__replyToEmail=no-reply@example.com
# SMTP settings
globalSettings__mail__smtp__host=smtp.example.com
globalSettings__mail__smtp__port=587
globalSettings__mail__smtp__username=bitwarden@example.com
globalSettings__mail__smtp__password=smtp_password
# Database connection
globalSettings__sqlServer__connectionString=Data Source=mssql;Initial Catalog=vault;User ID=bitwarden;Password=db_password
# Disable user registration (for private instances)
globalSettings__disableUserRegistration=true
# Logging
globalSettings__logLevel__default=Information SSL Certificate Configuration
Using Let’s Encrypt (Automatic)
Already configured during installation if selected.
Manual renewal:
./bitwarden.sh renewcert Using Custom Certificate
Place certificate files:
# Certificate and key
./bwdata/ssl/your-domain/certificate.crt
./bwdata/ssl/your-domain/private.key
# CA bundle
./bwdata/ssl/your-domain/ca.crt Update config.yml:
ssl:
certificate_path: /etc/bitwarden/ssl/your-domain
certificate_name: certificate.crt
key_name: private.key
ca_name: ca.crt Starting and Managing Bitwarden
Start Bitwarden
./bitwarden.sh start Stop Bitwarden
./bitwarden.sh stop Restart Bitwarden
./bitwarden.sh restart View Status
docker ps Expected containers:
bitwarden-nginxbitwarden-webbitwarden-apibitwarden-identitybitwarden-mssql(or postgres)bitwarden-attachmentsbitwarden-iconsbitwarden-notificationsbitwarden-eventsbitwarden-admin
View Logs
docker logs bitwarden-api
docker logs bitwarden-identity
docker logs -f bitwarden-api # Follow mode Initial Setup
Access Web Vault
Navigate to: https://vault.example.com
Create Master Account
- Click “Create Account”
- Enter email and strong master password
- (Optional) Create organization for team sharing
Configure Admin Panel
Access: https://vault.example.com/admin
Important settings:
General Settings
- Disable user registration (if private)
- Configure allowed domains
SMTP Settings
- Test email configuration
Two-Factor Authentication
- Enforce 2FA for organization
Policies
- Master password requirements
- Personal ownership restrictions
Upgrades and Updates
Check for Updates
./bitwarden.sh updateself
./bitwarden.sh update Upgrade Process
Best practices:
- Review release notes: https://bitwarden.com/help/releasenotes/
- Create VM snapshot or backup
- Schedule maintenance window
- Notify users of downtime
- Perform upgrade
- Test functionality
- Notify users of completion
Upgrade steps:
# 1. Stop Bitwarden
./bitwarden.sh stop
# 2. Update script and dependencies
./bitwarden.sh updateself
# 3. Update Bitwarden
./bitwarden.sh update
# 4. Rebuild containers
./bitwarden.sh rebuild
# 5. Start Bitwarden
./bitwarden.sh start Typical Upgrade Timeline
- Preparation: 15-30 minutes
- Downtime: 5-10 minutes
- Verification: 10-15 minutes
Breaking Changes to Watch
Common breaking changes in updates:
- SQL Server version support (e.g., dropping SQL Server 2019)
- Deprecated authentication methods (e.g., Kerberos)
- Logging method changes (e.g., syslog deprecation)
- Encryption scheme updates
- API version changes
Backup and Recovery
Critical Directories to Backup
./bwdata/env/ # Environment variables and secrets
./bwdata/core/attachments/ # Vault attachments
./bwdata/mssql/data/ # Database files
./bwdata/core/aspnet-dataprotection/ # Auth tokens and encrypted columns Backup Script
#!/bin/bash
# bitwarden-backup.sh
BACKUP_DIR="/backups/bitwarden"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BW_DIR="/home/bitwarden/bwdata"
# Stop Bitwarden
cd /home/bitwarden
./bitwarden.sh stop
# Create backup directory
mkdir -p "$BACKUP_DIR/$TIMESTAMP"
# Backup critical directories
tar -czf "$BACKUP_DIR/$TIMESTAMP/env.tar.gz" -C "$BW_DIR" env
tar -czf "$BACKUP_DIR/$TIMESTAMP/attachments.tar.gz" -C "$BW_DIR/core" attachments
tar -czf "$BACKUP_DIR/$TIMESTAMP/mssql-data.tar.gz" -C "$BW_DIR/mssql" data
tar -czf "$BACKUP_DIR/$TIMESTAMP/aspnet-dataprotection.tar.gz" -C "$BW_DIR/core" aspnet-dataprotection
# Start Bitwarden
./bitwarden.sh start
# Keep last 30 days
find "$BACKUP_DIR" -type d -mtime +30 -exec rm -rf {} +
echo "Backup completed: $BACKUP_DIR/$TIMESTAMP" Automate Backups
Cron job (monthly):
# Edit crontab
crontab -e
# Add line (runs 1st of month at 2 AM)
0 2 1 * * /home/bitwarden/bitwarden-backup.sh >> /var/log/bitwarden-backup.log 2>&1 Restore from Backup
#!/bin/bash
# bitwarden-restore.sh
BACKUP_DATE="20250101_020000"
BACKUP_DIR="/backups/bitwarden/$BACKUP_DATE"
BW_DIR="/home/bitwarden/bwdata"
# Stop Bitwarden
cd /home/bitwarden
./bitwarden.sh stop
# Restore directories
tar -xzf "$BACKUP_DIR/env.tar.gz" -C "$BW_DIR"
tar -xzf "$BACKUP_DIR/attachments.tar.gz" -C "$BW_DIR/core"
tar -xzf "$BACKUP_DIR/mssql-data.tar.gz" -C "$BW_DIR/mssql"
tar -xzf "$BACKUP_DIR/aspnet-dataprotection.tar.gz" -C "$BW_DIR/core"
# Fix permissions
chown -R bitwarden:bitwarden "$BW_DIR"
# Start Bitwarden
./bitwarden.sh start
echo "Restore completed from: $BACKUP_DIR" Authentication Integration
Azure AD / Entra ID
Configure in Bitwarden:
- Admin Panel → SSO → Configure
- Select OpenID Connect
- Enter Azure AD details:
- Authority:
https://login.microsoftonline.com/YOUR_TENANT_ID/v2.0 - Client ID: From Azure App Registration
- Client Secret: From Azure App Registration
- Authority:
Azure App Registration:
- Azure Portal → App registrations → New registration
- Name:
Bitwarden SSO - Redirect URI:
https://vault.example.com/sso-callback - Create client secret
- API permissions:
User.Read,profile,email
LDAP / Active Directory
Bitwarden supports LDAP sync for directory integration.
Configure LDAP sync:
# bwdata/env/global.override.env
globalSettings__ldap__server=ldap://dc.example.com
globalSettings__ldap__port=389
globalSettings__ldap__baseDn=DC=example,DC=com
globalSettings__ldap__username=CN=bitwarden,OU=Service Accounts,DC=example,DC=com
globalSettings__ldap__password=ldap_password Monitoring and Maintenance
Health Check
Check container health:
docker ps --format "table {{.Names}}\t{{.Status}}" Database connectivity:
docker exec -it bitwarden-mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 'your_password' -Q "SELECT @@VERSION" Log Monitoring
Setup log rotation:
// /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
} Restart Docker:
sudo systemctl restart docker Performance Tuning
Database maintenance (SQL Server):
-- Inside bitwarden-mssql container
USE vault;
GO
-- Update statistics
EXEC sp_updatestats;
GO
-- Rebuild indexes
EXEC sp_MSforeachtable 'ALTER INDEX ALL ON ? REBUILD';
GO Things worth getting right
Enforce a strong master password policy and require 2FA for every user. These two alone eliminate the vast majority of realistic attack paths.
Run automated backups of the directories listed above and test restore at least once. A backup you’ve never restored from is a backup you don’t have.
HTTPS only. Never expose the web vault over plain HTTP, even briefly. Limit access to management endpoints (admin panel, SSH) to specific source IPs where possible.
Keep the stack on current releases. Bitwarden ships security fixes regularly; running an old version on the open internet is asking for it.
For private instances, disable user registration in the admin panel so the only way in is via an account you create.
Troubleshooting
Common Issues
Container won’t start:
# Check logs
docker logs bitwarden-api
# Check disk space
df -h
# Verify permissions
ls -la ./bwdata Cannot access web vault:
# Check NGINX logs
docker logs bitwarden-nginx
# Verify SSL certificate
openssl s_client -connect vault.example.com:443
# Check firewall
sudo ufw status Email not sending:
# Test SMTP from container
docker exec -it bitwarden-api bash
telnet smtp.example.com 587 Database connection errors:
# Check database status
docker exec -it bitwarden-mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U sa
# Verify connection string
cat ./bwdata/env/global.override.env | grep connectionString Migration and Disaster Recovery
Migrate to New Server
- Prepare new server with same Bitwarden version
- Backup current installation
- Transfer backup files to new server
- Restore using restore script
- Update DNS to point to new server
- Test functionality thoroughly
High Availability
For mission-critical deployments:
- Load balancer in front of multiple Bitwarden instances
- Shared database (Azure SQL, AWS RDS)
- Shared storage for attachments (S3, Azure Blob)
- Geographic redundancy for disaster recovery
Additional Resources
- Official Documentation: https://bitwarden.com/help/
- Release Notes: https://bitwarden.com/help/releasenotes/
- Community Forums: https://community.bitwarden.com/
- GitHub Repository: https://github.com/bitwarden/server
Key Topics
Core Configuration
- Password Manager Backup and Recovery Strategies - Backup automation, disaster recovery
- Database Options for Self-Hosted Applications - SQL Server vs PostgreSQL configuration
- SMTP Email Configuration for Self-Hosted Services - Email delivery setup
- Reverse Proxy Configuration for Web Services - NGINX, Caddy, Traefik setup
- SSL Certificate Management - Certificate deployment and renewal
Related Services
- Vaultwarden Self-Hosted Deployment - Lightweight alternative for small teams
- Docker Compose Configuration for Password Managers - Container orchestration patterns