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

在服务器上创建项目目录:

Terminal window
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"

启动:

Terminal window
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

创建账号

用域名访问站点,应该能看到登录 / 注册页面。点击「创建账号」,填邮箱和主密码完成注册。

主密码一定要记牢,丢了没法找回。

关闭公开注册

创建好自己的账号后,在 .envdocker-compose.yml 里把 SIGNUPS_ALLOWED 设为 false,重建容器:

Terminal window
docker compose down && docker compose up -d

之后如果需要新增用户,通过管理面板邀请即可。

管理面板

Vaultwarden 内置 Web 管理面板,可以对所有用户、组织进行管理。

配置 ADMIN_TOKEN

生成强随机令牌:

Terminal window
openssl rand -base64 32

设为 ADMIN_TOKEN 环境变量,或更安全的方式 —— 用 Argon2 哈希存储:

Terminal window
docker exec -it vaultwarden /vaultwarden hash

按提示输入两次密码,将输出的 $argon2id$... 字符串设为 ADMIN_TOKEN。Docker Compose 中需将 $ 转义为 $$

访问

容器启动后访问 https://你的域名/admin,输入 ADMIN_TOKEN 即可进入后台。管理面板可以:

  • 查看所有注册用户、组织及角色
  • 移除用户 2FA、取消授权、禁用或删除用户
  • 查看系统诊断信息
  • 配置 SMTP、WebSocket 等

管理面板中保存的配置会写入 config.json优先级高于环境变量。如果改了环境变量但没生效,检查一下 config.json 是否覆盖了它。

客户端使用

  1. Bitwarden 下载页面 装客户端或浏览器插件
  2. 登录界面点左上角设置图标,服务器地址改成你的域名
  3. 用刚才注册的邮箱和主密码登录

Bitwarden 的 iOS、Android、Windows、macOS、Linux 客户端和浏览器插件全部兼容 Vaultwarden,跟用官方服务没区别。

实用技巧

URI 匹配优化:浏览器插件默认按「基础域名」匹配密码,会导致同域名下子站全部弹出来。建议在客户端设置 → 自动填充 → 默认 URI 匹配检测,改为 主机(Host)

Send 功能:安全分享文本或文件给他人。支持端到端加密、密码保护、自动过期,单文件最大 500MB。

两步验证(2FA):强烈建议开启。支持 TOTP(Authenticator App)、FIDO2 WebAuthn(硬件密钥)、邮箱验证码等方式。

密码生成器:内置密码生成器,可自定义长度和字符类型,也可生成易读的「密码短语」。

备份与恢复

密码数据属于一等重要数据,建议遵循 3-2-1 备份原则:至少 3 份副本、存于 2 种不同介质、其中 1 份异地存放。

手动备份

所有数据都在数据目录里:

Terminal window
docker stop vaultwarden
tar -czf vaultwarden-backup-$(date +%Y%m%d).tar.gz ./data
docker start vaultwarden

GPG 加密备份 + 定时任务

备份文件如果要传到云端,先加密再上传:

Terminal window
gpg --symmetric --cipher-algo AES256 vaultwarden-backup-$(date +%Y%m%d).tar.gz

配合 cron 自动化。创建 /opt/vaultwarden/backup.sh

#!/bin/bash
set -e
DATE=$(date +%Y%m%d)
BACKUP_DIR=/backup/vaultwarden
BACKUP_FILE=vaultwarden-$DATE.tar.gz
mkdir -p $BACKUP_DIR
cd /opt/vaultwarden
docker stop vaultwarden
tar -czf "$BACKUP_DIR/$BACKUP_FILE" ./data
docker 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"
Terminal window
# 每天凌晨 3 点执行
crontab -e
0 3 * * * /opt/vaultwarden/backup.sh

更新

更新 Vaultwarden 非常简单:

Terminal window
cd /opt/vaultwarden
docker compose pull
docker 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

常见问题

忘记主密码怎么办

主密码是端到端加密的,服务端无法找回。只能删除数据目录重新部署,所有密码数据无法恢复。务必把主密码记在安全的地方。

部署后网站打不开

  1. docker ps | grep vaultwarden 检查容器是否运行
  2. 检查反向代理端口号是否一致
  3. 确认 SSL 证书已正确配置

如何迁移数据到新服务器

Terminal window
# 旧服务器
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)可以批量编辑条目,但有几个坑:

  1. 大数量操作必须分批 sync。 300+ 条目不能一口气跑完,session 会过期。每处理 15 条执行一次 bw sync 刷新。
  2. bw CLI 适合少量操作,大量条目用 Web UI 拖拽更快。 脚本写迁移逻辑、Web UI 动手执行是最佳分工。
  3. 删除操作逐条确认,不批量。 可能同名不同实,需要打开看内容才能判断。

定期体检

养成习惯,半年翻一次密码库:有没有敏感数据还在明文、有没有新增重复、分类是否还合理。