Bitwarden-compatible password manager compose example.
Educational example only. Review every volume path, port, and credential before you run this. Do not copy production secrets into your wiki or git repo.
_shared/.env for non-secrets, _shared/.secret for credentialsmkdir -p /path/to/docker/stacks/vaultwarden
cd /path/to/docker/stacks/vaultwarden
# paste compose.yaml below, then:
docker compose pull
docker compose up -d
services:
vaultwarden:
env_file:
- /path/to/docker/stacks/_shared/.env
- /path/to/docker/stacks/_shared/.secret
image: vaultwarden/server:latest
container_name: vaultwarden
hostname: vaultwarden
environment:
# Domain (must be publicly accessible for OIDC callbacks)
- DOMAIN=https://YOUR_HOST.YOUR_DOMAIN #${VW_DOMAIN}
# Email Setup
- SMTP_HOST=YOUR_HOST.YOUR_DOMAIN #${EM_HOST}
- SMTP_FROM=vaultwarden@YOUR_DOMAIN #${EM_FROM}
- SMTP_PORT=25 #${EM_PORT}
- SMTP_SECURITY=off
- SMTP_SSL=false
# Use these only if your server requires authentication
#- SMTP_USERNAME=your_username
#- SMTP_PASSWORD=CHANGE_ME
# Database Setup
- DATABASE_URL=CHANGE_ME
# General settings
- SIGNUPS_ALLOWED=false # Recommended with SSO
# Admin page — ADMIN_TOKEN comes from _shared/.secret via env_file
# SSO / OIDC with Keycloak
- SSO_ENABLED=true
- SSO_ONLY=true # Disable email/password login (recommended)
- SSO_AUTHORITY=https://YOUR_HOST.YOUR_DOMAIN/realms/YOUR_REALM #/.well-known/openid-configuration # No trailing slash, exact issuer match
- SSO_CLIENT_ID=vaultwarden
# SSO_CLIENT_SECRET comes from _shared/.secret via env_file
- SSO_SCOPES=openid profile email offline_access
- SSO_PKCE=true
- SSO_AUTH_ONLY_NOT_SESSION=true
- SSO_CLIENT_CACHE_EXPIRATION=3600 # 1 hour cache for discovery
# Optional but recommended
- SSO_SIGNUPS_MATCH_EMAIL=true
#- SSO_ALLOW_UNKNOWN_EMAIL_VERIFICATION=false
- WEBSOCKET_ENABLED=true # If you need live sync (requires reverse proxy support)
logging:
driver: json-file
options:
max-file: ${DOCKERLOGGING_MAXFILE:-10} # Max number of log files
max-size: ${DOCKERLOGGING_MAXSIZE:-200k} # Max file size
volumes:
- /path/to/docker/data/vaultwarden/data:/data
ports:
- 30032:80
restart: unless-stopped
_shared/.secret.