TL;DR — Quick Summary
A comprehensive guide to self-hosting your own secure Bitwarden-compatible password manager using Docker Compose and Nginx.
Taking control of your own cybersecurity is the ultimate homelab achievement. By self-hosting Vaultwarden, you get the absolute premium power of a world-class password manager (Bitwarden) entirely within your own private perimeter.
In this guide, we will deploy Vaultwarden using Docker Compose and secure it for production use.
Step 1: Prepare the Host Environment
You need a Linux host with Docker and Docker Compose installed. First, create a secure directory so we don’t accidentally lose our SQLite database.
mkdir -p /opt/vaultwarden
cd /opt/vaultwarden
Step 2: The Docker Compose Configuration
Create a file named docker-compose.yml in your new directory. Paste the following optimal production configuration:
version: '3'
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: always
environment:
- WEBSOCKET_ENABLED=true
- SIGNUPS_ALLOWED=true
volumes:
- ./vw-data:/data
ports:
- 8080:80
Notice the line SIGNUPS_ALLOWED=true. This allows anyone who accesses your URL to create an account. We will change this to false later after you register your main account!
Step 3: Launch the Container
Deploy the container in detached mode:
docker-compose up -d
Verify that it started successfully without throwing exit codes:
docker-compose logs -f
Step 4: Reverse Proxy and SSL (Crucial)
Vaultwarden relies heavily on the browser’s Web Crypto API to decrypt your passwords locally. This API completely disables itself if the site is not served over strict HTTPS.
You must hide your local 8080 port behind a reverse proxy (like Nginx Proxy Manager).
- Open Nginx Proxy Manager.
- Create a Proxy Host mapping
vault.yourdomain.comto your server’s IP and port8080. - Enable “Request a new SSL Certificate” and enforce “Force SSL”.
Step 5: Disable Signups
Once your SSL is working, navigate to your domain, create your master account, and verify you can log in.
After you have registered your family members, aggressively lock down your instance by returning to your docker-compose.yml and modifying the environment block:
environment:
- WEBSOCKET_ENABLED=true
- SIGNUPS_ALLOWED=false
Restart the container to apply the lockdown:
docker-compose down && docker-compose up -d
Your passwords are now locally encrypted, self-hosted, and utterly impenetrable!