OpenBao Docker Compose 部署指南

OpenBao v2.7.1 的 Compose 部署实战:生产形态(pebbledb+分片封印)与 dev 形态两套编排文件、初始化解封全流程、数据持久化验证、TLS/auto-unseal 提示与升级清单。

OpenBaoOpenBao2026/10/17

OpenBao Docker Compose 部署指南

‍‍​​‌​> 目标:用 Compose 把 OpenBao v2.7.1 跑起来——覆盖生产形态(pebbledb 持久化 + Shamir 分片)与 dev 体验形态两套配置文件,走完"启动 → 初始化 → 解封 → 冒烟 → 数据持久化验证 → 升级"全流程;命令与回显均在本机实测(敏感密钥值已脱敏)。

一、环境信息

  • 操作系统:Ubuntu 22.04 LTS(x86_64)
  • OpenBao:openbao/openbao:2.7.1(与 latest 当前指向同一版本,实测 bao version 回显 OpenBao v2.7.1 (a5db72cef75c24b920ade02065b18dd8eb666bac), committed 2026-10-01T15:32:54Z)
  • Compose:Docker Compose v2(docker compose version 回显 Docker Compose version v2.39.2)
  • 端口规划:宿主机 8200:8200(API/UI),集群端口 8201 仅容器网络内部使用
  • 目录规划:
/opt/data/openbao/compose/
├── docker-compose.yml      # 编排文件(本篇第三节)
├── config/
│   └── config.hcl          # OpenBao 服务端配置(本篇第三节)
└── file/                   # pebbledb 数据目录(挂载到容器内 /openbao/file)
  • 容器命名:openbao-2.7.1-compose(生产形态演示实例)

版本与环境确认:

docker compose version
docker image inspect openbao/openbao:2.7.1 --format '{{.Config.Entrypoint}} {{.Config.User}}'

实测回显:

Docker Compose version v2.39.2
[/usr/local/bin/docker-entrypoint.sh] openbao

⚠️ 注意:镜像默认以非 root 用户 openbao 运行,而 bind mount 的宿主机目录属主为 root 时容器内无法写入(实测启动即失败)。两种解法:user: "0" 以 root 启动(入口脚本会自动 chown 后降权到 openbao 用户),或预先把宿主机目录属主改为容器内 openbao 用户的 uid。本文采用前者,已在第四节说明。

二、部署形态总览

OpenBao 有两种官方运行形态,Compose 下都能落地,按用途选择:

形态存储与封印适用本文实测
生产形态(bao server -config=...)pebbledb 持久化 + 5 分片封印,需手动 init/unseal正式环境第三节~第四节
dev 形态(bao server -dev)内存存储、自动初始化解封、单分片本地体验/联调,重启数据即失第五节

⚠️ 注意:OpenBao v2.7.0 起 storage "file" 已被移除(官方 CHANGELOG),本地持久化默认用 pebbledb,生产高可用建议用集成 Raft(单机 Compose 演示场景本文用 pebbledb)。同时 v2.7.1 已不支持 disable_mlock = false 配置(会拒绝启动),配置文件中不要出现该行。

三、Compose 配置文件

3.1 服务端配置 config/config.hcl

cat > /opt/data/openbao/compose/config/config.hcl <<'EOF'
ui = true

storage "pebbledb" {
  path = "/openbao/file"
}

listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_disable = 1
}

api_addr = "http://127.0.0.1:8200"
EOF

配置说明:

配置项作用
ui = true开启内置 Web UI(8200 端口直接访问)
storage "pebbledb"本地持久化存储,path 指向容器内数据目录
listener "tcp"API 监听地址;tls_disable = 1 为 HTTP(TLS 配置见第七节提示)
api_addr对外通告地址,客户端重定向/集群通信使用

3.2 编排文件 docker-compose.yml

cat > /opt/data/openbao/compose/docker-compose.yml <<'EOF'
services:
  openbao:
    image: openbao/openbao:2.7.1
    container_name: openbao-2.7.1-compose
    user: "0"                       # 入口脚本以 root chown 数据目录后自动降权到 openbao 用户
    ports:
      - "8200:8200"
    volumes:
      - ./file:/openbao/file        # pebbledb 数据(必须持久化,随实例保留)
      - ./config:/openbao/config    # 服务端配置
    command: bao server -config=/openbao/config/config.hcl
    restart: unless-stopped
EOF

配置说明:

配置项作用
image固定版本 tag 2.7.1,避免 latest 随上游漂移;升级见第八节
user: "0"见第一节注意事项:解决 root 属主目录的写权限问题
ports宿主机固定 8200:8200
volumes数据与配置目录 bind mount;如需挂载 CA/证书,见第七节
command覆盖镜像默认命令,以生产形态启动并指定配置
restartunless-stopped:随系统/引擎自愈拉起(拉起后仍需解封,见第六节)

3.3 客户端环境变量提示

容器内外的 bao CLI 均通过 BAO_* 环境变量定位服务与凭证,常用如下(均为官方 CLI 支持变量):

变量作用示例
BAO_ADDR服务 API 地址http://127.0.0.1:8200
BAO_TOKEN认证 tokens.xxxx…
BAO_CACERT校验服务端证书所用 CA 路径/etc/openbao/ca.crt
BAO_CLIENT_CERT / BAO_CLIENT_KEYmTLS 客户端证书与私钥/etc/openbao/client.crt
BAO_SKIP_VERIFY跳过证书校验(仅联调用)true

💡 说明:若采用第七节的 HTTPS 监听,宿主机 CLI 需要设置 BAO_CACERT 指向自签 CA 才能正常连接。

四、启动与初始化

4.1 启动服务

cd /opt/data/openbao/compose
docker compose up -d
docker compose ps
docker compose logs openbao

实测回显(启动日志节选首尾):

 Container openbao-2.7.1-compose  Started
NAME                   IMAGE                    COMMAND                  SERVICE   CREATED         STATUS         PORTS
openbao-2.7.1-compose  openbao/openbao:2.7.1    "docker-entrypoint.s…"   openbao   3 seconds ago   Up 2 seconds   0.0.0.0:8200->8200/tcp
openbao-2.7.1-compose  | ==> OpenBao server configuration:
openbao-2.7.1-compose  |              Api Address: http://127.0.0.1:8200
openbao-2.7.1-compose  |                  Cgo: disabled
openbao-2.7.1-compose  |       Cluster Address: https://0.0.0.0:8201
openbao-2.7.1-compose  |           Go Version: go1.27.1
openbao-2.7.1-compose  |  Listener 1: tcp (addr: "0.0.0.0:8200", cluster address: "0.0.0.0:8201", max_request_duration: "1m30s", max_request_json_memory: "34078720", max_request_json_strings: "1000", max_request_size: "33554432", tls: "disabled")
openbao-2.7.1-compose  |              Log Level:
openbao-2.7.1-compose  |          Recovery Mode: false
openbao-2.7.1-compose  |                Storage: pebbledb
openbao-2.7.1-compose  |                Version: OpenBao v2.7.1, committed 2026-10-01T15:32:54Z
openbao-2.7.1-compose  |            Version Sha: a5db72cef75c24b920ade02065b18dd8eb666bac
openbao-2.7.1-compose  | ==> OpenBao server started! Log data will stream in below:

宿主机确认连通(未初始化状态):

export BAO_ADDR=http://127.0.0.1:8200
bao status
Key                Value
---                -----
Seal Type          shamir
Initialized        false
Sealed             true
Total Shares       0
Threshold          0
Unseal Progress    0/0
Unseal Nonce       n/a
Version            2.7.1
Commit Date        2026-10-01T15:32:54Z
Storage Type       pebbledb
HA Enabled         false

4.2 初始化(init)

bao operator init -key-shares=5 -key-threshold=3

实测回显(分片与 token 已脱敏,结构真实):

Unseal Key 1: 8OIdyoytCFMS3lCl…(已脱敏)
Unseal Key 2: 5rlGJi4zV9Znhkfc…(已脱敏)
Unseal Key 3: yBg9A6BIcZ8QFRTK…(已脱敏)
Unseal Key 4: x/tP1NB2mHYE5vW1…(已脱敏)
Unseal Key 5: +Cq0y4rGFuU+ViWW…(已脱敏)

Initial Root Token: s.7hSAb0oP…(已脱敏)

Vault initialized with 5 key shares and a key threshold of 3. Please securely
distribute the key shares printed above. When the Vault is re-sealed,
restarted, or stopped, you must supply at least 3 of these keys to unseal it
before it can start servicing requests.

Vault does not store the generated root key. Without at least 3 keys to
reconstruct the root key, Vault will remain permanently sealed!

It is possible to generate new unseal keys, provided you have a quorum
of existing unseal keys shares. See "bao operator rotate-keys" for more
information.

⚠️ 注意:这一屏输出只出现一次,请立即把 5 个分片离线分存、root token 按需吊销(机制详解见原理篇"常见误区")。

4.3 三次解封(unseal)

bao operator unseal "8OIdyoytCFMS3lCl…(分片 1 完整值)"
bao operator unseal "5rlGJi4zV9Znhkfc…(分片 2 完整值)"
bao operator unseal "yBg9A6BIcZ8QFRTK…(分片 3 完整值)"

实测回显逐次对比:

Sealed             true
Unseal Progress    1/3
---
Sealed             true
Unseal Progress    2/3
---
Sealed          false

4.4 冒烟验证(K/V 写读)

⚠️ 注意:全新初始化的正式模式没有默认 secret/ 挂载(bao secrets list 只有 cubbyhole/、identity/、sys/),需要先启用 K/V 引擎。

export BAO_TOKEN="s.7hSAb0oP…(root token 完整值)"
bao secrets enable -path=secret kv-v2
bao kv put secret/compose app=openbao mode=compose
bao kv get secret/compose

实测回显(启用与写入):

Success! Enabled the kv secrets engine at: secret/
= Secret Path =
secret/data/compose

======= Metadata =======
Key                Value
---                -----
created_time       2026-10-17T10:05:21.331465482Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

读取验证:

===== Data =====
Key     Value
---     -----
app     openbao
mode    compose

4.5 数据持久化验证(重启容器)

docker compose restart openbao
docker compose exec openbao bao status

实测回显(重启后回到封印态,这正是"数据已持久化、根密钥未加载"的体现):

Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    0/3
Unseal Nonce       n/a
Version            2.7.1
Commit Date        2026-10-01T15:32:54Z
Storage Type       pebbledb
HA Enabled         false

重新解封后原数据完整可读:

bao operator unseal "8OIdyoytCFMS3lCl…(分片 1)"
bao operator unseal "5rlGJi4zV9Znhkfc…(分片 2)"
bao operator unseal "yBg9A6BIcZ8QFRTK…(分片 3)"
bao kv get secret/compose
Sealed          false
===== Data =====
Key     Value
---     -----
app     openbao
mode    compose

五、dev 形态(可选体验)

dev 形态一条命令起服务:内存存储、自动初始化解封、单分片单阈值,Unseal Key 与 Root Token 直接打印在日志横幅。仅用于体验与联调,严禁存真数据。

在 Compose 下可单独建一个体验用编排(如 docker-compose.dev.yml):

services:
  openbao-dev:
    image: openbao/openbao:2.7.1
    container_name: openbao-2.7.1-devmode
    ports:
      - "8200:8200"
    command: bao server -dev -dev-listen-address=0.0.0.0:8200 -dev-root-token-id=dev-root-token-123456
docker compose -f docker-compose.dev.yml up -d
docker logs openbao-2.7.1-devmode | tail -8

实测日志横幅(节选):

Unseal Key: Ygne6VQzgq3knwdb3BbP…(已脱敏)
Root Token: dev-root-token-123456

Development mode should NOT be used in production installations!
export BAO_ADDR=http://127.0.0.1:8200 BAO_TOKEN=dev-root-token-123456
bao kv put secret/demo app=openbao env=dev
bao kv get secret/demo

实测回显(get):

===== Data =====
Key    Value
---    -----
app    openbao
env    dev

⚠️ 注意:dev 形态默认只监听容器内 127.0.0.1:8200,宿主机端口转发会连不上——实测必须显式 -dev-listen-address=0.0.0.0:8200 才能从外部访问。体验完 docker compose -f docker-compose.dev.yml down 即可(数据本就不落盘)。

六、封印、解封与 auto-unseal 提示

  • 为什么每次重启后都封印:OpenBao 重启后根密钥不在内存,必须凑齐阈值分片解封才能服务(4.5 节实测),这是 barrier 安全模型的正常行为,不是故障。
  • 人工解封的运维成本:restart: unless-stopped 只能拉起进程,不能自动解封;无人值守/频繁重启场景建议评估 auto-unseal:把根密钥保护外包给云 KMS、transit(另一个 OpenBao 实例)等,服务启动时自动解封。
  • auto-unseal 接入提示:在 config.hcl 中增加 seal "..." 块(如 seal "transit" 指向另一实例的 transit 引擎,或 seal "awskms"/seal "gcpkms" 指向云 KMS),并为其配置凭据;首次切换 auto-unseal 需要走一次重封流程。具体参数以官方文档 Configuration 一节为准,本文未实测该路径,不做展开。
  • 解封操作安全提示:分片不要提交到 CI/聊天记录;换分片用 bao operator rotate-keys(v2.7.1 已废弃 operator rekey,实测返回 405)。

七、TLS 与证书挂载提示

本文实测为 HTTP 监听(tls_disable = 1)。生产建议启用 TLS,两步提示:

  1. 证书挂载:把服务端证书、私钥与 CA 挂进容器,例如在 docker-compose.yml 的 volumes 中追加:
      - ./tls/server.crt:/openbao/tls/server.crt:ro
      - ./tls/server.key:/openbao/tls/server.key:ro
      - ./tls/ca.crt:/openbao/tls/ca.crt:ro
  1. 监听配置:config.hcl 的 listener 段替换为 TLS 模式(示例提示,需自备证书后启用):
listener "tcp" {
  address         = "0.0.0.0:8200"
  tls_cert_file   = "/openbao/tls/server.crt"
  tls_key_file    = "/openbao/tls/server.key"
}

客户端侧配套设置 BAO_CACERT=/etc/openbao/ca.crt(或 mTLS 时加 BAO_CLIENT_CERT/BAO_CLIENT_KEY),api_addr 同步改为 https://。以上为接入提示,请按自身证书体系调整后实测。

八、升级

  • 镜像升级步骤:修改 docker-compose.yml 中的版本 tag → docker compose pull → docker compose up -d → 服务自动回到封印态 → 用现有分片解封 → 核对 bao status 的 Version 与 bao secrets list 挂载完整性。
  • 升级前备份:解封态对数据做逻辑备份(集成 Raft 用 bao operator raft snapshot save;pebbledb 单机可停机快照 ./file 目录),分片与 root token 保障到位后再动手。
  • v2.6 → v2.7 重大变更核对清单(依据官方 CHANGELOG,本文实测复现):
    • storage "file" 已移除:旧配置启动报 unknown storage type file,本地持久化改用 pebbledb;
    • mlock 支持移除:配置含 disable_mlock = false 会拒绝启动(实测报错 OpenBao has dropped support for mlock. Please remove the line "disable_mlock" = false ... and disable or encrypt swap instead),改由系统层关闭/加密 swap;
    • bao operator rekey 已废弃:实测 405,改用 bao operator rotate-keys;
    • 部分 auth/seal 能力转为外部插件(HSM/PKCS#11 封印、Kerberos/LDAP/RADIUS 认证等):升级前核对所用能力是否需要单独安装插件。
  • 版本选择:跟随官方补丁线(如 2.7.x)及时打补丁;镜像 tag 固定到具体小版本(本文 2.7.1),不要在生产用 latest。

九、参考链接