Passbolt 5.16.0 Docker Compose 部署指南

Passbolt 5.16.0 社区版 Docker Compose 双容器部署实测指南:应用与 MariaDB 10.11 编排、显式子网规划、首启初始化日志、首管理员注册与 GPGAuth 登录验证、数据持久化与等价 docker run 形态,全部命令与回显实测于 2026-10-19。

PassboltDocker Compose安装部署2026/10/19

Passbolt 5.16.0 Docker Compose 部署指南

目标:在一台 Linux 服务器上以 Docker Compose 部署 Passbolt 社区版(CE)5.16.0,完成应用与数据库双容器编排、HTTPS 健康检查、首管理员注册与登录验证,并给出等价的 docker run 形态。本文全部命令、参数与回显均在一台真实服务器上逐条实测(实测日期 2026-10-19),禁止照抄未经验证的输出。

一、环境信息

本文实测环境如下:

项目值
服务器 IP192.168.146.128
操作系统Linux x86_64
Docker 版本29.8.1(api 1.56),linux/amd64
Compose 版本Docker Compose version v5.5.1
Passbolt 镜像passbolt/passbolt:5.16.0-1-ce
数据库镜像mariadb:10.11
对外端口8113(映射到容器 443/HTTPS)
自定义网络passbolt-net,子网 10.89.41.0/24
部署目录/opt/data/quzuo/passbolt-5.16.0/

版本说明:Passbolt 5.16.0 为官方最新稳定版(发布名 "Enjoy the Silence",2026-09-17 发布,实查 GitHub passbolt/passbolt_api Releases),预发布版本 v5.17.0-test.1 不予采用。选型背景与同类产品对比见《Passbolt 5.16.0 介绍与选型指南》。

二、镜像选型说明

2.1 Passbolt 官方镜像

Passbolt 官方维护 Docker 镜像,仓库为 passbolt/passbolt(源码仓库 https://github.com/passbolt/passbolt_docker)。镜像标签遵循「API 版本-镜像修订号-版本线」格式,本次实测选用:

  • passbolt/passbolt:5.16.0-1-ce:API 5.16.0、镜像修订号 1、社区版(CE)。社区版对应 AGPL-3.0 许可;若使用商业订阅则选 -pro 结尾的标签(如 5.16.0-1-pro),本文不涉及。
  • 镜像内已集成 Nginx + PHP-FPM + GnuPG + cron,由 supervisord 统一拉起,单容器即提供完整 Web 服务,无需额外安装 PHP 扩展。
  • 首次启动时入口脚本 /docker-entrypoint.sh 会自动完成:数据库 schema 迁移、服务器 GPG 密钥对生成(写入 /etc/passbolt/gpg)、JWT 密钥对生成(写入 /etc/passbolt/jwt),无需手工执行安装命令。

2.2 数据库镜像

选择 mariadb:10.11:Passbolt 5.x 支持 MySQL 8 / MariaDB 10.11 及以上的受支持版本,MariaDB 10.11 为官方 Docker 镜像库中维护活跃的 LTS 线,与 Passbolt 5.16.0 实测兼容(数据库迁移、注册、登录、共享全流程通过)。

2.3 镜像拉取

网络受限环境下可通过代理拉取(代理地址按实际环境替换):

docker pull passbolt/passbolt:5.16.0-1-ce
docker pull mariadb:10.11

实测两个镜像均拉取成功,docker images 中可见 passbolt/passbolt 与 mariadb 两个仓库。

三、前置条件

3.1 端口复核

规划宿主端口 8113 对外服务(映射容器 443)。动工前先复核端口未被占用:

ss -ltn | grep 8113

占用时该命令有输出,需先腾退端口;空闲时无任何输出(本文实测时 8113 空闲)。部署完成后再复核,可见监听:

LISTEN 0      4096         0.0.0.0:8113       0.0.0.0:*    users:(("docker-proxy",pid=2560335,fd=8))
LISTEN 0      4096            [::]:8113       0.0.0.0:*    users:(("docker-proxy",pid=2560343,fd=8))

3.2 创建自定义网络并显式指定子网

自定义网络必须显式指定 --subnet,按序取用 10.89.x.0/24 网段(本批次取 10.89.41.0/24),禁用 192.168.0.0/16 与 100.64.0.0/16 网段:

docker network create --subnet 10.89.41.0/24 passbolt-net

创建后确认网络参数,并验证主机默认路由不受影响(外部地址仍走物理网卡 ens33):

docker network inspect passbolt-net --format '{{.Name}} {{.Scope}} {{(index .IPAM.Config 0).Subnet}}'
ip route get 192.168.1.62

实测回显:

passbolt-net local 10.89.41.0/24
192.168.1.62 via 192.168.146.2 dev ens33 src 192.168.146.128 uid 0
    cache

ip route get 确认目标 192.168.1.62 仍经 ens33 物理网卡转发,自定义网段未劫持主机路由。

3.3 规划数据目录

在部署目录放置 Compose 文件(本文实测路径 /opt/data/quzuo/passbolt-5.16.0/docker-compose-ce.yaml)。数据卷由 Compose 按项目名自动创建命名卷(见「五、数据持久化说明」),无需提前手工建卷。

四、部署步骤

4.1 编写 Compose 文件

以下为本次实测使用的 docker-compose-ce.yaml 完整内容(Passbolt 5.16.0 实测通过版本):

services:
  db:
    image: mariadb:10.11
    container_name: passbolt-5.16.0-db
    restart: unless-stopped
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "true"
      MYSQL_DATABASE: "passbolt"
      MYSQL_USER: "passbolt"
      MYSQL_PASSWORD: "P4ssb0lt"
    volumes:
      - database_volume:/var/lib/mysql
    networks:
      - default
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 12

  passbolt:
    image: passbolt/passbolt:5.16.0-1-ce
    container_name: passbolt-5.16.0-app
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    environment:
      APP_FULL_BASE_URL: https://192.168.146.128:8113
      DATASOURCES_DEFAULT_HOST: "db"
      DATASOURCES_DEFAULT_USERNAME: "passbolt"
      DATASOURCES_DEFAULT_PASSWORD: "P4ssb0lt"
      DATASOURCES_DEFAULT_DATABASE: "passbolt"
      PASSBOLT_GPG_SERVER_KEY_FINGERPRINT: "226CD536A314A96C54E0EBCBA5968499BA1A4E66"
      PASSBOLT_SSL_FORCE: "true"
      PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED: "true"
      EMAIL_TRANSPORT_DEFAULT_HOST: "192.168.146.128"
      EMAIL_TRANSPORT_DEFAULT_PORT: "1025"
      EMAIL_TRANSPORT_DEFAULT_TLS: "false"
      EMAIL_DEFAULT_FROM: "passbolt@passbolt.local"
      EMAIL_DEFAULT_FROM_NAME: "Passbolt"
    volumes:
      - gpg_volume:/etc/passbolt/gpg
      - jwt_volume:/etc/passbolt/jwt
    command:
      [
        "/usr/bin/wait-for.sh",
        "-t",
        "0",
        "db:3306",
        "--",
        "/docker-entrypoint.sh",
      ]
    ports:
      - "8113:443"
    networks:
      - default
    healthcheck:
      test: ["CMD", "curl", "-kfs", "https://localhost/healthcheck/status.json"]
      interval: 15s
      timeout: 5s
      retries: 20
      start_period: 60s

networks:
  default:
    external: true
    name: passbolt-net

volumes:
  database_volume:
  gpg_volume:
  jwt_volume:

关键取舍说明:

  • PASSBOLT_GPG_SERVER_KEY_FINGERPRINT 的值是首启自动生成的服务端密钥指纹,首次部署时可先不填,首启完成后按「七、配置参数说明」的 7.2 节查询真实指纹再回填并重建容器,用于固定密钥、防止密钥环被意外重建。
  • 端口映射选 8113:443 而非官方示例默认的 80:80:官方镜像 443 端口提供自签证书的 HTTPS 服务,配合 PASSBOLT_SSL_FORCE=true 时 80 端口仅做重定向,生产使用应直接走 HTTPS。
  • depends_on 使用 condition: service_healthy,确保数据库探活通过后应用容器才启动;command 中的 wait-for.sh 是官方镜像自带脚本,作为第二重保险等待 3306 可连。

4.2 启动

docker compose -p passbolt-5160 -f /opt/data/quzuo/passbolt-5.16.0/docker-compose-ce.yaml up -d

实测回显(注意 db Healthy 说明健康门槛生效):

 Container passbolt-5.16.0-db Waiting
 Container passbolt-5.16.0-db Healthy
 Container passbolt-5.16.0-app Starting
 Container passbolt-5.16.0-app Started

4.3 首启初始化日志

查看应用容器首启日志(docker logs passbolt-5.16.0-app),关键过程逐字实录如下:

wait-for.sh: waiting for db:3306 without a timeout
wait-for.sh: db:3306 is available after 0 seconds
gpg: keybox '/var/lib/passbolt/.gnupg/pubring.kbx' created
gpg: /var/lib/passbolt/.gnupg/trustdb.gpg: trustdb created
gpg: key A5968499BA1A4E66: public key "Passbolt default user <passbolt@yourdomain.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg: key A5968499BA1A4E66: "Passbolt default user <passbolt@yourdomain.com>" not changed
gpg: key A5968499BA1A4E66: secret key imported
Total number processed: 1
  unchanged: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1
 Installing passbolt

     ____                  __          ____
    / __ \____  _____ ____/ /_  ____  / / /_
   / /_/ / __ `/ ___/ ___/ __ \/ __ \/ / __/
  / ____/ /_/ (__  |__  ) /_/ / /_/ / / /
 /_/    \__,_/____/____/_.___/\____/_/\__/

 Open source password manager for teams
-------------------------------------------------------------------------------
Running baseline checks, please wait...
Running migrations

     ____                  __          ____
    / __ \____  _____ ____/ /_  ____  / / /_
   / /_/ / __ `/ ___/ ___/ __ \/ __ \/ / __/
  / ____/ /_/ (__  |__  ) /_/ / /_/ / / /
 /_/    \__,_/____/____/_.___/\____/_/\__/

 Open source password manager for teams
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 Running migration scripts.
-------------------------------------------------------------------------------
using migration paths
 - /etc/passbolt/Migrations
using seed paths
using environment default
using adapter mysql
using database passbolt
ordering by creation time

All Done. Took 0.0058s
Clearing cake caches
Clearing _cake_model_
Cleared _cake_model_ cache
Clearing _cake_core_
The `_cake_core_` cache configuration does not exist.
Clearing _cake_translations_
Cleared _cake_translations_ cache
Enjoy! ☮

日志解读:

  • wait-for.sh: db:3306 is available after 0 seconds:数据库就绪等待通过。
  • gpg: key A5968499BA1A4E66 ... secret keys imported:服务端 GPG 密钥(指纹后 16 位 A5968499BA1A4E66)从挂载卷导入运行时密钥环——首启时生成的密钥文件落在 gpg 卷,之后每次重启都会走这个导入动作。
  • Running migration scripts ... All Done:数据库 schema 迁移完成。
  • Enjoy! ☮:初始化结束标志。
  • 若数据库卷已存在表结构(例如复用旧卷重建容器),日志中在 Running baseline checks 之后还会出现一行提示 Some tables are already present in the database. A new installation would override existing data. Please use --force to proceed anyway.——这是全新安装检查的提示,迁移脚本随后照常执行;数据库为全新空卷时不会出现该行。

4.4 健康状态验证

等待健康检查转为 healthy 后核对双容器状态:

docker ps --filter "name=passbolt-5.16.0" --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"

实测回显:

NAMES                 IMAGE                           STATUS                    PORTS
passbolt-5.16.0-app   passbolt/passbolt:5.16.0-1-ce   Up 13 minutes (healthy)   80/tcp, 0.0.0.0:8113->443/tcp, [::]:8113->443/tcp
passbolt-5.16.0-db    mariadb:10.11                   Up 48 minutes (healthy)   3306/tcp

再从服务器侧验证健康检查端点与首页可达性:

curl -kfs https://192.168.146.128:8113/healthcheck/status.json
curl -kfs -o /dev/null -w "%{http_code}\n" https://192.168.146.128:8113/

实测回显:

{"header":{"id":"989bbc3b-252f-40a4-8d24-16f551bd9749","status":"success","servertime":1792391074,"action":"f52ecf6c-8e82-5f3d-ab73-f6df46eb71b5","message":"OK","url":"\/healthcheck\/status.json","code":200},"body":"OK"}

首页返回 302(HTTPS 强制开启时的正常重定向行为)。至此服务本体部署完成。

4.5 注册首管理员

Passbolt 的管理员不是配置文件写死的,而是通过「注册链接」创建。使用容器内置 CLI 生成注册链接:

docker exec passbolt-5.16.0-app su -s /bin/bash -c "bin/cake passbolt register_user -u charlie@passbolt.local -f Charlie -l Brown -r admin" www-data

参数说明:-u 登录邮箱、-f 名、-l 姓、-r 角色(首管理员用 admin)。实测回显:

User saved successfully.
To start registration follow the link provided in your mailbox or here:
https://192.168.146.128:8113/setup/start/cadec237-fc23-4aeb-acfb-18135a4f6dbe/c775c848-5b36-4633-8a25-0edf2ee6e72f

用浏览器打开该链接即可进入安装向导:生成或导入用户 OpenPGP 密钥(必须 RSA 3072 及以上,详见 11.4 节实测)、设置口令、下载恢复套件,完成后即可以该账号登录 Web 界面。

注册链接对应的服务端状态可用 JSON 端点验证(链接末尾加 .json):

curl -kfs https://192.168.146.128:8113/setup/start/cadec237-fc23-4aeb-acfb-18135a4f6dbe/c775c848-5b36-4633-8a25-0edf2ee6e72f.json

实测回显(节选,active: false 表明账号等待完成注册流程):

{
    "header": {
        "id": "c7e04caf-57e5-4322-9e0e-ab229c3cbc04",
        "status": "success",
        "servertime": 1792391388,
        "action": "50ca4a19-b782-5842-bd2b-f59e9ff4eef9",
        "message": "The operation was successful.",
        "url": "/setup/start/cadec237-fc23-4aeb-acfb-18135a4f6dbe/c775c848-5b36-4633-8a25-0edf2ee6e72f.json",
        "code": 200
    },
    "body": {
        "user": {
            "id": "cadec237-fc23-4aeb-acfb-18135a4f6dbe",
            "role_id": "a8a4bc6a-6aee-40d3-a610-fbbc899cc18b",
            "username": "charlie@passbolt.local",
            "active": false,
            "deleted": false,
            "disabled": null,
            "created": "2026-10-19T06:25:31+00:00",
            "modified": "2026-10-19T06:25:31+00:00",
            "profile": {
                "id": "d71379ce-123f-4e2d-b299-bf0e439f80a2",
                "user_id": "cadec237-fc23-4aeb-acfb-18135a4f6dbe",
                "first_name": "Charlie",
                "last_name": "Brown",
                "created": "2026-10-19T06:25:31+00:00",
                "modified": "2026-10-19T06:25:31+00:00"
            },
            "role": {
                "id": "a8a4bc6a-6aee-40d3-a610-fbbc899cc18b",
                "name": "admin",
                "description": "Organization administrator"
            }
        }
    }
}

4.6 登录验证

完成注册的账号通过 GPGAuth 协议登录(浏览器扩展内完成密钥握手)。服务器侧验证登录握手与 API 可用性:实测以管理员账号走完整 GPGAuth 两段握手(Stage 1 获取服务端加密令牌、Stage 2 回传解密结果),服务端返回:

You are successfully logged in.

响应头同时携带 x-gpgauth-authenticated: true 并下发 passbolt_session 会话 Cookie;随后携带该会话请求 GET /users.json 成功列出全部已注册用户:

['admin@passbolt.local', 'bob@passbolt.local', 'charlie@passbolt.local']

登录即验证通过,部署链路(数据库 → 应用 → 注册 → 认证 → API)全通。

五、数据持久化说明

Compose 定义了三个命名卷,全部数据落在卷内,容器重建不丢:

卷(实际名称)容器挂载点内容
passbolt-5160_database_volume/var/lib/mysql(db 容器)全部业务数据:用户、资源元数据、密文、审计日志
passbolt-5160_gpg_volume/etc/passbolt/gpg(app 容器)服务端 GPG 密钥对
passbolt-5160_jwt_volume/etc/passbolt/jwt(app 容器)JWT 签名密钥对

卷名前缀 passbolt-5160 来自 Compose 项目名(目录名 passbolt-5.16.0 去掉点号规范化而来)。核对命令与实测回显:

docker volume ls --format "{{.Name}}" | grep -i passbolt
passbolt-5160_database_volume
passbolt-5160_gpg_volume
passbolt-5160_jwt_volume

GPG 卷与 JWT 卷内文件实测清单:

docker exec passbolt-5.16.0-app ls -la /etc/passbolt/gpg
docker exec passbolt-5.16.0-app ls -la /etc/passbolt/jwt
/etc/passbolt/gpg:
total 20
drwxrwx--- 2 root     www-data 4096 Oct 19 05:35 .
drwxrwx--- 6 root     www-data 4096 Oct 16 07:19 ..
-rw-rw-r-- 1 www-data www-data 2456 Oct 19 05:35 serverkey.asc
-rw-rw-r-- 1 www-data www-data 5091 Oct 19 05:35 serverkey_private.asc

/etc/passbolt/jwt:
total 16
drwxr-x--- 2 root www-data 4096 Oct 19 05:35 .
drwxrwx--- 6 root www-data 4096 Oct 16 07:19 ..
-rw-r----- 1 root www-data 3272 Oct 19 05:35 jwt.key
-rw-r----- 1 root www-data  800 Oct 19 05:35 jwt.pem

三个卷的备份/恢复直接对应「数据库转储 + 两个密钥目录打包」,实操序列见《Passbolt 5.16.0 安全加固指南》备份恢复章节。特别强调:gpg 卷一旦丢失,服务端身份密钥即丢失,已注册用户将无法完成 GPGAuth 握手;jwt 卷丢失则所有在线会话失效,务必纳入备份范围。

六、环境变量表

本次实测在 Compose 中配置的全部环境变量:

变量实测值作用
APP_FULL_BASE_URLhttps://192.168.146.128:8113对外访问基地址,必须与浏览器实际访问地址完全一致
DATASOURCES_DEFAULT_HOSTdb数据库主机名(Compose 服务名)
DATASOURCES_DEFAULT_USERNAMEpassbolt数据库用户
DATASOURCES_DEFAULT_PASSWORDP4ssb0lt数据库口令
DATASOURCES_DEFAULT_DATABASEpassbolt数据库名
PASSBOLT_GPG_SERVER_KEY_FINGERPRINT226CD536A314A96C54E0EBCBA5968499BA1A4E66固定服务端 GPG 密钥指纹
PASSBOLT_SSL_FORCEtrue强制 HTTPS,80 端口请求重定向到 443
PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLEDtrue关闭 Web 界面的 SMTP 设置端点,防止改库行为
EMAIL_TRANSPORT_DEFAULT_HOST192.168.146.128邮件服务器地址(v5 正确写法)
EMAIL_TRANSPORT_DEFAULT_PORT1025邮件服务器端口
EMAIL_TRANSPORT_DEFAULT_TLSfalse是否使用 TLS 连接邮件服务器
EMAIL_DEFAULT_FROMpassbolt@passbolt.local发件人地址
EMAIL_DEFAULT_FROM_NAMEPassbolt发件人显示名

数据库侧对应四个 MYSQL_* 变量(MYSQL_RANDOM_ROOT_PASSWORD: "true" 表示 root 口令随机生成、不落配置):MYSQL_DATABASE/MYSQL_USER/MYSQL_PASSWORD 分别与 Passbolt 侧 DATASOURCES_DEFAULT_* 三项对应,两侧必须一致。

七、配置参数说明

7.1 APP_FULL_BASE_URL(最高频事故源)

该地址参与 Passbolt 的路由生成、CSRF 域校验与注册链接拼接,必须与浏览器地址栏访问地址逐字符一致(含协议与端口)。实测教训:将其配成服务器另一个网段地址 https://192.168.1.62:8113 后,curl 访问直接空响应,改回本机真实地址 https://192.168.146.128:8113 并重建容器后立即恢复。修改该变量需重建容器(up -d 会因环境变量变化自动重建)。

7.2 PASSBOLT_GPG_SERVER_KEY_FINGERPRINT

首启时入口脚本自动生成 RSA 3072 服务端密钥并导出到 gpg 卷。查询真实指纹的实测命令与回显:

docker exec passbolt-5.16.0-app gpg --homedir /var/lib/passbolt/.gnupg --fingerprint 226CD536A314A96C54E0EBCBA5968499BA1A4E66
gpg: WARNING: unsafe ownership on homedir '/var/lib/passbolt/.gnupg'
pub   rsa3072 2026-10-19 [SC]
      226C D536 A314 A96C 54E0  EBCB A596 8499 BA1A 4E66
uid           [ unknown] Passbolt default user <passbolt@yourdomain.com>
sub   rsa3072 2026-10-19 [E]

首次部署时该变量可留空,从上述命令取到指纹后回填到 Compose 并重建,可防止容器重建时误生成第二把服务端密钥。密钥文件的权限与保护措施见《Passbolt 5.16.0 安全加固指南》。

7.3 PASSBOLT_SSL_FORCE

设为 true 后应用容器内 80 端口的 HTTP 请求被 302 重定向到 HTTPS,并输出 HSTS 头(max-age=31536000)。健康检查命令因此必须写 https:// 并带 -k(自签证书不校验):

test: ["CMD", "curl", "-kfs", "https://localhost/healthcheck/status.json"]

漏掉 -k 会导致健康检查永远失败、容器状态卡在 health: starting。

7.4 邮件相关变量(v5 版本重要变更)

v5 镜像中旧的 SMTP_* 前缀环境变量已废弃(实测在 5.16.0-1-ce 镜像内全量 grep 无任何引用),配置邮件必须使用 EMAIL_TRANSPORT_DEFAULT_HOST/PORT/TLS 与 EMAIL_DEFAULT_FROM/EMAIL_DEFAULT_FROM_NAME。修改后重建容器,用内置命令实测发信:

docker exec passbolt-5.16.0-app su -s /bin/bash -c "bin/cake passbolt send_test_email --to=admin@passbolt.local" www-data

实测在 1025 端口自建 SMTP 收信台接收到测试邮件,发件人为 Passbolt <passbolt@passbolt.local>,与 EMAIL_DEFAULT_FROM* 配置一致。

7.5 数据库连接参数

DATASOURCES_DEFAULT_* 四项即 CakePHP 的默认数据源。首次部署后修改数据库指向属于高危操作(涉及 schema 与密文),建议仅在迁移数据库时按官方恢复流程操作,日常不做变更。

八、配置文件挂载

镜像的关键配置目录与挂载建议:

容器路径内容是否必须挂卷
/etc/passbolt/gpgserverkey.asc / serverkey_private.asc(服务端 GPG 密钥对)必须,丢失将导致所有用户无法登录握手
/etc/passbolt/jwtjwt.key / jwt.pem(JWT 签名密钥对)必须,丢失则全体会话失效
/etc/passbolt.php应用主配置文件(PHP 数组格式)可选,环境变量优先级更高,本方案未挂载
/var/lib/passbolt/.gnupg运行时密钥环(非持久目录,每次启动从 gpg 卷导入重建)不需要

说明:Passbolt 官方镜像的配置优先级是「环境变量 → /etc/passbolt.php → 镜像内置 app.default.php」,环境变量方式足以覆盖绝大多数部署需求;需要精细控制(如自定义安全策略默认值)时再挂载 /etc/passbolt.php。可用的环境变量全集与取值见《Passbolt 5.16.0 配置参数详解》。

九、等价 docker run 形态

不使用 Compose 时,以下两条 docker run 命令与上述 Compose 栈等价(实测通过:双容器 healthy、健康端点返回 200)。先启动数据库:

docker run -d --name passbolt-5.16.0-db \
  --restart unless-stopped \
  --network passbolt-net \
  --network-alias db \
  -e MYSQL_RANDOM_ROOT_PASSWORD=true \
  -e MYSQL_DATABASE=passbolt \
  -e MYSQL_USER=passbolt \
  -e MYSQL_PASSWORD=P4ssb0lt \
  -v passbolt-5160_database_volume:/var/lib/mysql \
  --health-cmd="healthcheck.sh --connect --innodb_initialized" \
  --health-interval=10s --health-timeout=5s --health-retries=12 \
  mariadb:10.11

确认数据库 healthy 后启动应用:

docker run -d --name passbolt-5.16.0-app \
  --restart unless-stopped \
  --network passbolt-net \
  -p 8113:443 \
  -e APP_FULL_BASE_URL=https://192.168.146.128:8113 \
  -e DATASOURCES_DEFAULT_HOST=db \
  -e DATASOURCES_DEFAULT_USERNAME=passbolt \
  -e DATASOURCES_DEFAULT_PASSWORD=P4ssb0lt \
  -e DATASOURCES_DEFAULT_DATABASE=passbolt \
  -e PASSBOLT_GPG_SERVER_KEY_FINGERPRINT=226CD536A314A96C54E0EBCBA5968499BA1A4E66 \
  -e PASSBOLT_SSL_FORCE=true \
  -e PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED=true \
  -e EMAIL_TRANSPORT_DEFAULT_HOST=192.168.146.128 \
  -e EMAIL_TRANSPORT_DEFAULT_PORT=1025 \
  -e EMAIL_TRANSPORT_DEFAULT_TLS=false \
  -e EMAIL_DEFAULT_FROM=passbolt@passbolt.local \
  -e EMAIL_DEFAULT_FROM_NAME=Passbolt \
  -v passbolt-5160_gpg_volume:/etc/passbolt/gpg \
  -v passbolt-5160_jwt_volume:/etc/passbolt/jwt \
  --health-cmd="curl -kfs https://localhost/healthcheck/status.json" \
  --health-interval=15s --health-timeout=5s --health-retries=20 \
  passbolt/passbolt:5.16.0-1-ce \
  /usr/bin/wait-for.sh -t 0 db:3306 -- /docker-entrypoint.sh

与 Compose 的差异点说明:

  • --network-alias db:Compose 中应用通过服务名 db 解析数据库;docker run 没有服务名,用网络别名补齐,使 DATASOURCES_DEFAULT_HOST=db 保持不变。
  • 依赖顺序手工保证:先等 db 容器 healthy(docker inspect --format '{{.State.Health.Status}}' passbolt-5.16.0-db 输出 healthy),再启动应用。
  • 应用容器末尾的 wait-for.sh 命令串即 Compose 中的 command 字段。

实测结果:应用容器约 1 分钟后转为 healthy,健康端点返回:

{"header":{"id":"7972b20d-6489-4d41-94e5-54222a682a8a","status":"success","servertime":1792391218,"action":"f52ecf6c-8e82-5f3d-ab73-f6df46eb71b5","message":"OK","url":"\/healthcheck\/status.json","code":200},"body":"OK"}

验证完毕后按相反顺序移除两个容器即可切回 Compose 管理(命名卷保留,数据不受影响)。

十、常用运维命令

以下命令均在实测环境逐条执行过(-p passbolt-5160 与 -f 指向 4.1 节的文件,下称 $PF 简写:-f /opt/data/quzuo/passbolt-5.16.0/docker-compose-ce.yaml):

# 查看栈状态(含健康状态)
docker compose -p passbolt-5160 -f $PF ps

# 跟踪应用日志
docker compose -p passbolt-5160 -f $PF logs -f passbolt

# 重启单个服务
docker compose -p passbolt-5160 -f $PF restart passbolt

# 停止(保留卷与网络)
docker compose -p passbolt-5160 -f $PF down

# 重新拉起(配置变更后自动重建受影响容器)
docker compose -p passbolt-5160 -f $PF up -d

# 执行官方健康检查全量诊断
docker exec passbolt-5.16.0-app su -s /bin/bash -c "bin/cake passbolt healthcheck" www-data

升级操作:将 Compose 中镜像 tag 换到目标版本(如 5.16.0-1-ce → 新版本号),执行 docker pull 后 up -d,入口脚本会自动执行数据库迁移;升级前务必先完成「数据库转储 + gpg/jwt 卷打包」三件套备份(序列见《Passbolt 5.16.0 安全加固指南》),避免跨版本回退无门。

十一、常见问题

以下问题均为本次实测真实遇到并解决:

11.1 curl 访问空响应

现象:curl https://<服务器IP>:8113/ 无任何返回。原因:APP_FULL_BASE_URL 配成了另一个网段的地址,与实际访问地址不一致。解决:改为本机真实 IP(实测 https://192.168.146.128:8113)后 up -d 重建容器。

11.2 应用容器一直 starting

排查顺序:先看 docker logs passbolt-5.16.0-app 是否停在 wait-for.sh: waiting for db:3306(数据库未就绪或 DATASOURCES_DEFAULT_HOST 写错);再看健康检查命令是否漏了 -k(自签证书场景 curl -fs 会因证书校验失败永远不通过)。

11.3 register_user 报 Unknown short option

bin/cake passbolt register_user -F 报错 Error: Unknown short option F``。v5 已废弃 v4 的 -F 强制参数,名与姓分别用 -f/-l(见 4.5 节实测命令),不确定时先执行 bin/cake passbolt register_user --help 查看当前用法。

11.4 用户密钥被拒:The key size must match security recommendations.

注册向导中生成 RSA 2048 用户密钥时,服务端拒绝并返回 The key size must match security recommendations.(实测 HTTP 400)。解决:用户密钥选择 RSA 3072 及以上后重新提交即可通过。这是服务端强校验行为,属预期安全策略而非故障。

11.5 SMTP 环境变量不生效

使用旧文档中的 SMTP_HOST/SMTP_PORT 等变量后,发信日志仍显示连接 localhost:25。原因:5.x 镜像已全面改用 EMAIL_TRANSPORT_DEFAULT_* 前缀,旧变量名不再被读取(实测镜像内零引用)。按 7.4 节变量名重配并重建容器后,测试邮件发送成功。

11.6 数据库卷复用时出现 --force 提示

日志出现 Some tables are already present in the database. A new installation would override existing data. Please use --force to proceed anyway.。这不是报错:数据库卷已有表结构时入口脚本的保护性提示,迁移脚本随后正常执行(见 4.3 节日志解读);全新空卷不会出现该行。

11.7 端口 8113 被占用

up -d 报端口绑定失败时,ss -ltnp | grep 8113 找到占用进程腾退,或改用其他宿主端口并同步修改 APP_FULL_BASE_URL(端口必须与地址一致,见 7.1 节)。

十二、参考链接