跳到正文
LUNA.TEL创造,创新,有爱。
技术 阅读约 8 分钟

Vaultwarden 自托管密码库实战:Docker + Nginx + 宝塔证书

用 Docker 部署 Vaultwarden,配合 Nginx 反向代理、宝塔证书和正确的首次注册顺序,搭建自己的 Bitwarden 兼容密码库。

砂糖橘猫 26.10.2026 暂无评论

浏览器自带密码管理确实方便,但密码、通行密钥和二步验证备份长期放在浏览器账号里,迁移和审计都不太自由。Vaultwarden 是一个用 Rust 编写的轻量级 Bitwarden 兼容服务端,资源占用低,支持 Docker 部署,适合放在自己的 NAS、VPS 或家庭服务器上。下面按“Nginx → Docker → Vaultwarden → 证书 → 反向代理”的顺序,把整套服务搭起来。

适用环境:Ubuntu 22.04 / Debian 11+,一台有公网 IP 的服务器,一个已经解析到该服务器的域名。本文用 vault.example.com 作为示例,实际使用时全部替换成自己的域名。

一、先理解整体结构

Vaultwarden 容器内部监听 80 端口,主机上映射到 127.0.0.1:8000,只允许本机访问;Nginx 对外提供 443,负责 HTTPS 和反向代理。这样 8000 端口不会直接暴露到公网,证书和访问控制都集中在 Nginx 上。

浏览器 / 手机 App / 浏览器扩展
            │ HTTPS 443
            ▼
          Nginx
            │ http://127.0.0.1:8000
            ▼
   Vaultwarden 容器 :80
            │
            ▼
      ./vw-data(SQLite、附件、密钥)

需要准备的东西:

  • 域名一条 A 记录,指向服务器公网 IP;
  • 服务器安全组或防火墙放行 80 和 443;
  • 不要放行 8000,除非你明确知道自己在做什么;
  • 一个强随机字符串作为 Vaultwarden 管理后台的 ADMIN_TOKEN。

二、安装 Nginx

先更新软件源并安装 Nginx,设置开机自启:

apt update
apt install -y nginx
systemctl enable nginx
systemctl start nginx
systemctl status nginx

看到 active (running) 就说明 Nginx 已经正常启动。如果服务器上已经有宝塔、1Panel 或其他面板,先确认它们是否已经占用 80/443,避免重复安装和端口冲突。

systemctl status nginx 显示 active running
Nginx 启动状态,看到 active (running) 即可继续。图片来自原文。

三、安装 Docker 和 Compose 插件

使用 Docker 官方脚本安装,脚本内容建议先打开看一眼再执行:

curl -fsSL https://get.docker.com | bash
systemctl enable --now docker
docker --version
docker compose version

新版 Docker 已经内置 docker compose 子命令,不再需要单独安装旧版 docker-compose。如果系统提示 curl: command not found,先执行 apt install curl -y。如果 docker compose version 报错,检查 Docker 版本和 Compose 插件是否安装完整。

docker version 命令输出
确认 Docker 客户端和服务端都已安装。图片来自原文。

四、部署 Vaultwarden

创建工作目录并进入:

mkdir -p /opt/vaultwarden
cd /opt/vaultwarden
nano compose.yaml

写入下面的 Compose 配置。这里把宿主机端口绑定在 127.0.0.1,让 Vaultwarden 只能被本机 Nginx 访问:

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      DOMAIN: "https://vault.example.com"
      SIGNUPS_ALLOWED: "true"
      ADMIN_TOKEN: "把这里换成 openssl rand -hex 32 生成的随机值"
    volumes:
      - ./vw-data:/data
    ports:
      - "127.0.0.1:8000:80"

先生成管理令牌:

openssl rand -hex 32

把输出填到 ADMIN_TOKEN。这个值相当于 Vaultwarden 管理后台的钥匙,不要提交到 Git,也不要用短密码。

为什么先让注册开着:Vaultwarden 的网页端账户需要通过注册流程创建。如果一开始就设置 SIGNUPS_ALLOWED=false,又没有任何已有账户,首次使用会无法创建账户。正确做法是先设为 true,注册完自己的账户后立即改回 false 并重启容器。

启动并检查:

docker compose up -d
docker compose ps
docker logs --tail=50 vaultwarden

看到容器状态为 running,且端口映射是 127.0.0.1:8000->80/tcp,说明服务端已经启动。此时直接访问 http://服务器IP:8000 只能从服务器本机测试,公网访问应走下一步的 Nginx。

docker ps 显示 vaultwarden 运行状态和端口映射
docker ps 中的 Vaultwarden 容器与端口映射。图片来自原文。

五、申请证书并配置 HTTPS

可以用宝塔 / 1Panel 申请 Let’s Encrypt 免费证书,也可以用 certbot。下面以面板申请为例:

  1. 在面板中新建站点,域名填写 vault.example.com,类型选择纯静态;
  2. 进入站点设置 → SSL → 申请 Let’s Encrypt 证书;
  3. 申请成功后,复制完整证书链和私钥。

把证书放到 Nginx 能读取的位置:

mkdir -p /etc/letsencrypt/live/vault.example.com/
nano /etc/letsencrypt/live/vault.example.com/fullchain.pem
nano /etc/letsencrypt/live/vault.example.com/privkey.pem
chmod 700 /etc/letsencrypt/live/vault.example.com/
chmod 600 /etc/letsencrypt/live/vault.example.com/*.pem

注意续签问题:上面是手动复制路径,证书续签后不会自动更新这两个文件。如果使用宝塔自动续签,建议 Nginx 直接指向宝塔实际的证书目录,或者在续签后增加复制/重载 Nginx 的钩子。证书路径写错或权限过大,Nginx 会报 cannot load certificate。

宝塔面板 SSL 证书已部署界面
面板中证书申请成功后的界面。图片来自原文。

六、配置 Nginx 反向代理

创建站点配置:

nano /etc/nginx/sites-available/vault.example.com

写入 HTTP 跳转、HTTPS、反向代理,以及 Vaultwarden 通知所需的 WebSocket 转发:

server {
    listen 80;
    server_name vault.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name vault.example.com;

    ssl_certificate /etc/letsencrypt/live/vault.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/vault.example.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        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:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }

    location /notifications/hub/negotiate {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
    }
}

启用配置并测试:

ln -s /etc/nginx/sites-available/vault.example.com /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx

如果 nginx -t 输出 syntax is ok 和 test is successful,再用浏览器访问 https://vault.example.com。出现 Vaultwarden 登录界面,说明证书和反代都已经打通。

nginx -t 配置测试成功
nginx -t 通过后再 reload,避免把错误配置带到线上。图片来自原文。

七、首次使用与账户安全

首次部署时保持 SIGNUPS_ALLOWED=true,在网页端注册自己的账户,完成邮箱验证(如果配置了 SMTP)并登录。随后立即把 SIGNUPS_ALLOWED 改为 false,重启容器:

docker compose up -d --force-recreate
docker compose ps

Vaultwarden 的管理后台在 /admin,登录时使用前面设置的 ADMIN_TOKEN。管理后台可以查看用户、组织、邀请和诊断信息,不要把它和普通用户登录混为一谈。

浏览器访问 Vaultwarden 登录界面,HTTPS 生效
HTTPS 生效后打开 Vaultwarden 登录页。图片来自原文。

注册完成后,建议立刻做几件事:

  • 设置强主密码,并开启两步验证;
  • 保存好恢复代码,不要只存在同一台设备里;
  • 在手机 App 和浏览器扩展里填写 https://vault.example.com,不要填 8000 端口;
  • 不要多人共用管理员令牌;
  • 关闭公开注册后,新成员通过管理后台邀请加入。

八、密码库、Send 与生成器

登录后可以创建登录、支付卡、身份、笔记和 SSH 密钥等条目。日常使用时,浏览器扩展负责自动填充,手机 App 负责移动端访问;服务端只保存加密后的密码库数据,主密码不会以明文保存在服务器上。

Vaultwarden 创建账户页面
创建第一个账户。图片来自原文引用的知乎使用指南。
Vaultwarden 登录后的密码库界面
登录后的密码库主界面。图片来自原文引用的知乎使用指南。

“Send”适合临时分享文本或文件,链接可以设置有效期和访问次数;生成器可以生成随机密码、短语和用户名。把常用站点的密码逐步迁移进去后,再开启弱密码报告,集中处理重复密码和弱密码。

Vaultwarden 密码库条目列表
密码库条目列表。图片来自原文引用的知乎使用指南。
Vaultwarden Send 界面
Send 适合临时发送敏感文本。图片来自原文引用的知乎使用指南。
Vaultwarden 密码生成器
密码生成器支持随机密码、短语和用户名。图片来自原文引用的知乎使用指南。

九、备份、升级与日常维护

Vaultwarden 的全部持久化数据都在 /opt/vaultwarden/vw-data,包括 SQLite 数据库、附件和 RSA 密钥。备份时先停止容器,避免复制到写入中的数据库:

cd /opt/vaultwarden
docker compose stop
tar czf vaultwarden-$(date +%F).tar.gz vw-data
docker compose start

把备份文件放到另一台机器或对象存储,并定期做恢复演练。只备份数据库不备份附件和密钥,恢复后可能出现附件丢失或会话异常。

升级镜像:

cd /opt/vaultwarden
docker compose pull
docker compose up -d

升级前先备份,升级后检查 docker compose ps 和 docker logs。不要在生产环境直接使用 :latest 而不做回滚准备;可以固定具体版本标签,确认稳定后再升级。

十、常见问题

现象 原因与处理
docker-compose: command not found 使用新版 docker compose(中间是空格),或安装 Compose 插件。
cannot load certificate 证书路径不对、文件不存在,或权限不正确;检查 fullchain.pem 和 privkey.pem,目录 700、文件 600。
options-ssl-nginx.conf 不存在 配置里引用了 certbot 的 include,但本机没有该文件;删掉这行,使用本文的 SSL 参数。
页面能打开但无法注册 SIGNUPS_ALLOWED 被设为 false;临时设为 true 注册后再关闭,或通过管理后台邀请。
502 Bad Gateway Vaultwarden 容器没运行,或 Nginx 代理端口不是 8000;执行 curl -I http://127.0.0.1:8000 检查。
通知不实时 WebSocket 没有被反代;检查 /notifications/hub 和 Upgrade 头。
管理后台进不去 没有设置 ADMIN_TOKEN,或令牌与环境变量不一致;修改后重启容器。
证书续签后浏览器报错 手动复制的证书没有随续签更新;改用实际证书路径或增加续签钩子。

十一、安全清单

  • 只暴露 80/443,8000 绑定 127.0.0.1;
  • 使用强主密码、两步验证和恢复代码;
  • ADMIN_TOKEN 使用长随机值,不写入公开仓库;
  • 关闭公开注册,成员通过邀请加入;
  • 定期备份 vw-data,并验证恢复;
  • 保持 Docker 镜像和 Nginx 更新;
  • 不要把数据库、私钥或备份目录放到 Web 根目录。

十二、写在最后

Vaultwarden 的部署不复杂,真正容易翻车的是顺序和细节:先让容器在本机跑通,再上证书和反向代理;注册完账户后关闭公开注册;证书续签要能更新到 Nginx 实际读取的文件。按这个顺序做,密码库就能稳定地为自己和小团队服务。

参考资料与图片出处

本文根据 O Meow 的原文《🐾 别再让浏览器替你存密码了!喵手把手教你自托管 Vaultwarden(附宝塔证书 + Nginx 反代)》整理重写,原文地址:https://www.oops.net.cn/113/。

部署过程截图来自上述原文;账户、密码库、Send 和生成器截图来自原文所引用的知乎专栏《Vaultwarden 使用指南》:https://zhuanlan.zhihu.com/p/1972727866396538429。图片版权归原作者,仅用于本文说明;如需转载图片,请先获得原作者授权。

Vaultwarden 项目:https://github.com/dani-garcia/vaultwarden

作者

砂糖橘猫

生物专业。业余研究网络技术,通讯技术,银行业。业余无线电A类证书,呼号BG2GSM。精通英语,俄语,想学日语,德语。

4 篇文章 全部文章

讨论

暂无评论

发表评论

邮箱不会公开。带 * 的为必填项。

人机验证

由 Cloudflare Turnstile 提供保护。