Docker Compose 部署 Vaultwarden 自托管密码管理服务
前言
以前我用 KeePass 配合坚果云 WebDAV 同步,桌面端体验一般,浏览器插件也不太好用。后来了解到 Bitwarden,开源免费、全平台支持,官方还提供了 Docker 镜像可以自建服务端。
不过官方镜像要求服务器内存 2G 以上,对于轻量云服务器有点吃力。社区用 Rust 重写的 Vaultwarden 把资源要求降到了 512MB,功能上完全兼容 Bitwarden 所有客户端。
准备工作
- 一台 Linux 服务器(512MB 内存以上)
- Docker 和 Docker Compose 已安装
- 一个域名解析到服务器,配好 SSL 证书(可以用 Nginx Proxy Manager 或 Caddy)
部署
docker-compose.yml
在服务器上创建项目目录:
mkdir -p /opt/vaultwarden && cd /opt/vaultwarden写入 docker-compose.yml:
services: vaultwarden: image: vaultwarden/server:latest container_name: vaultwarden restart: unless-stopped volumes: - ./data:/data environment: DOMAIN: "https://你的域名" SIGNUPS_ALLOWED: "false" ADMIN_TOKEN: "你的随机令牌" WEBSOCKET_ENABLED: "true" ports: - "127.0.0.1:6789:80"启动:
docker compose up -d反向代理配置(Nginx)
在 Nginx 站点配置中添加:
location / { proxy_pass http://127.0.0.1:6789; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;}
location /notifications/hub { proxy_pass http://127.0.0.1:6789; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";}
location /notifications/hub/negotiate {2 collapsed lines
proxy_pass http://127.0.0.1:6789;}第二个 /notifications/hub 块是 WebSocket 配置,让客户端可以实时同步。
配置完 nginx -t && nginx -s reload。
创建账号
用域名访问站点,应该能看到登录 / 注册页面。点击「创建账号」,填邮箱和主密码完成注册。
主密码一定要记牢,丢了没法找回。
关闭公开注册
创建好自己的账号后,在 .env 或 docker-compose.yml 里把 SIGNUPS_ALLOWED 设为 false,重建容器:
docker compose down && docker compose up -d之后如果需要新增用户,通过管理面板邀请即可。
管理面板
Vaultwarden 内置 Web 管理面板,可以对所有用户、组织进行管理。
配置 ADMIN_TOKEN
生成强随机令牌:
openssl rand -base64 32设为 ADMIN_TOKEN 环境变量,或更安全的方式 —— 用 Argon2 哈希存储:
docker exec -it vaultwarden /vaultwarden hash按提示输入两次密码,将输出的 $argon2id$... 字符串设为 ADMIN_TOKEN。Docker Compose 中需将 $ 转义为 $$。
访问
容器启动后访问 https://你的域名/admin,输入 ADMIN_TOKEN 即可进入后台。管理面板可以:
- 查看所有注册用户、组织及角色
- 移除用户 2FA、取消授权、禁用或删除用户
- 查看系统诊断信息
- 配置 SMTP、WebSocket 等
管理面板中保存的配置会写入 config.json,优先级高于环境变量。如果改了环境变量但没生效,检查一下 config.json 是否覆盖了它。
客户端使用
- 去 Bitwarden 下载页面装客户端或浏览器插件
- 登录界面点左上角设置图标,服务器地址改成你的域名
- 用刚才注册的邮箱和主密码登录
Bitwarden 的 iOS、Android、Windows、macOS、Linux 客户端和浏览器插件全部兼容 Vaultwarden,跟用官方服务没区别。
实用技巧
URI 匹配优化:浏览器插件默认按「基础域名」匹配密码,会导致同域名下子站全部弹出来。建议在客户端设置 → 自动填充 → 默认 URI 匹配检测,改为 主机(Host)。
Send 功能:安全分享文本或文件给他人。支持端到端加密、密码保护、自动过期,单文件最大 500MB。
两步验证(2FA):强烈建议开启。支持 TOTP(Authenticator App)、FIDO2 WebAuthn(硬件密钥)、邮箱验证码等方式。
密码生成器:内置密码生成器,可自定义长度和字符类型,也可生成易读的「密码短语」。
备份与恢复
密码数据属于一等重要数据,建议遵循 3-2-1 备份原则:至少 3 份副本、存于 2 种不同介质、其中 1 份异地存放。
手动备份
所有数据都在数据目录里:
docker stop vaultwardentar -czf vaultwarden-backup-$(date +%Y%m%d).tar.gz ./datadocker start vaultwardenGPG 加密备份 + 定时任务
备份文件如果要传到云端,先加密再上传:
gpg --symmetric --cipher-algo AES256 vaultwarden-backup-$(date +%Y%m%d).tar.gz配合 cron 自动化。创建 /opt/vaultwarden/backup.sh:
#!/bin/bashset -eDATE=$(date +%Y%m%d)BACKUP_DIR=/backup/vaultwardenBACKUP_FILE=vaultwarden-$DATE.tar.gz
mkdir -p $BACKUP_DIR
cd /opt/vaultwardendocker stop vaultwardentar -czf "$BACKUP_DIR/$BACKUP_FILE" ./datadocker start vaultwarden
gpg --batch --yes --passphrase "$GPG_PASSPHRASE" \ --symmetric --cipher-algo AES256 "$BACKUP_DIR/$BACKUP_FILE"4 collapsed lines
find $BACKUP_DIR -name "*.tar.gz*" -mtime +30 -delete
echo "Backup completed: $BACKUP_FILE.gpg"# 每天凌晨 3 点执行crontab -e0 3 * * * /opt/vaultwarden/backup.sh更新
更新 Vaultwarden 非常简单:
cd /opt/vaultwardendocker compose pulldocker compose up -d数据目录不受影响。建议关注 GitHub Releases,每个月拉一次新镜像。
安全加固
以非 root 用户运行:在 docker-compose.yml 中加 user: "1000:1000"。
关闭密码提示:管理面板中取消勾选「Show password hints」,避免泄露密码线索。
配置 fail2ban:多次登录失败后自动封禁 IP。详见 Vaultwarden Fail2Ban 设置。
只允许域名访问:确保 Nginx 不响应 IP 直连请求,公网 IP 会被不断扫描。
常用环境变量
| 变量 | 说明 | 示例 |
|---|---|---|
SIGNUPS_ALLOWED | 是否允许公开注册 | true / false |
ADMIN_TOKEN | 管理面板访问令牌 | 随机字符串或 Argon2 哈希 |
DOMAIN | 服务域名 | https://vault.example.com |
WEBSOCKET_ENABLED | 开启实时同步 | true / false |
SMTP_HOST | 邮件服务器地址 | smtp.qq.com |
SMTP_PORT | 邮件服务器端口 | 587 |
LOG_FILE | 日志文件路径 | /data/vaultwarden.log |
更详细的配置看 Vaultwarden Wiki。
常见问题
忘记主密码怎么办
主密码是端到端加密的,服务端无法找回。只能删除数据目录重新部署,所有密码数据无法恢复。务必把主密码记在安全的地方。
部署后网站打不开
docker ps | grep vaultwarden检查容器是否运行- 检查反向代理端口号是否一致
- 确认 SSL 证书已正确配置
如何迁移数据到新服务器
# 旧服务器tar -czf vaultwarden-data.tar.gz /opt/vaultwarden/data# scp 到新服务器后解压到相同路径,再 docker compose up -d所有密码库和配置都在 data 目录里。
可以多用户使用吗
创建第一个账号后关闭公开注册,之后通过管理员面板邀请其他用户。
密码库维护与优化
部署只是第一步。用久了之后密码库会自然膨胀 —— 条目堆积、没有分类、敏感数据写在明文 Notes 里。我用了几年攒了 348 条,花一个下午做了一轮优化。
常见问题
翻一遍密码库,大概率会看到这些:
- 敏感数据明文存 Notes。API Key、Recovery Code 直接写在 Notes 里,导出时一目了然。应该迁入 Hidden 自定义字段。
- 重复条目。名字相同不代表重复,得打开看 username 和 uri 才能判断。
- 没有文件夹分类。SSH 密钥、API 密钥、社交账号全混在 No Folder 下。
- IP 地址命名。16 个条目直接用 IP 命名,完全看不出是什么服务。
四阶段优化
| Phase | 目标 | 风险 |
|---|---|---|
| 1. 安全加固 | 敏感数据从 Notes 迁入 Hidden 自定义字段 | 低 |
| 2. 去重 | 检查并删除真重复条目 | 中(删除操作) |
| 3. 建文件夹 | 分类到文件夹 | 低 |
| 4. 规范命名 | IP 条目改成「服务 - 用途」格式 | 低 |
文件夹结构参考
📁 服务器 & SSH → 所有 SSH 密钥和登录信息📁 VPS & 面板 → VPS 商家的控制面板登录📁 邮箱 → 各类邮箱账号📁 域名 & DNS → Cloudflare、Namesilo 等📁 API & 密钥 → API Key、Token📁 开发工具 → GitHub、Docker、Vercel 等📁 国内服务 → 阿里云、腾讯云等📁 其他 → 不好分类的bw CLI 批量操作经验
Bitwarden CLI(bw)可以批量编辑条目,但有几个坑:
- 大数量操作必须分批 sync。 300+ 条目不能一口气跑完,session 会过期。每处理 15 条执行一次
bw sync刷新。 - bw CLI 适合少量操作,大量条目用 Web UI 拖拽更快。 脚本写迁移逻辑、Web UI 动手执行是最佳分工。
- 删除操作逐条确认,不批量。 可能同名不同实,需要打开看内容才能判断。
定期体检
养成习惯,半年翻一次密码库:有没有敏感数据还在明文、有没有新增重复、分类是否还合理。

