BigBlueButton 3.0.39 Docker Compose 部署指南

BigBlueButton 3.0.39 Compose 部署:bigbluebutton/docker 社区编排 17 服务栈一键部署、.env 与自签/正式证书两种形态、Greenlight 管理员创建、Blocked hosts 与 ChecksumError 排障、API 全链路验证与数据持久化实测(2026-10-27 实测)。

BigBlueButtonBigBlueButton视频会议WebRTC自托管2026/10/27

BigBlueButton 3.0.39 Docker Compose 部署指南

目标:用官方社区编排项目 bigbluebutton/docker 一键部署 BigBlueButton 3.0.39 全家桶(核心服务 + FreeSWITCH + webrtc-sfu + Greenlight 前端 + coturn 等 17 个服务),完成 .env 配置、编排文件生成、启动、Greenlight 管理员创建、BBB HTTP API 全链路验证(getMeetings/create/join/end)与数据持久化实测,并给出镜像选型、服务清单、资源占用、等价 docker run 与常见问题排障。全部命令与回显均在 Docker 29.9.2 + Compose v5.6.1 环境实测采集(2026-10-27),组件背景见《BigBlueButton 4.0.0 介绍与选型指南》。

一、环境信息

本文所有命令在以下环境实测:

  • 服务器系统:Ubuntu 24.04(x86_64,内核 7.0.0-38-generic)
  • Docker:29.9.2(docker --version → Docker version 29.9.2, build 7c95437)
  • Docker Compose:v5.6.1(docker compose version → Docker Compose version v5.6.1)
  • 编排项目:https://github.com/bigbluebutton/docker (master 分支,2026-10-27 克隆;README 自述「Docker version of BigBlueButton 3.0」「version: 3.0.39」,并注明「currently missing: livekit」——即该编排形态当前覆盖 3.0.39,尚未覆盖 4.0 的 LiveKit 媒体栈)
  • 部署目录:/opt/bbb-docker/(Compose 项目名 bbb-3-0-39-stack)
  • 服务器 IP:10.89.58.3(EXTER­NAL_IPv4 配置值,部署于独立隔离网段 10.89.58.0/24)
  • Web 端口:80/443(haproxy 统一入口);内部端口 48081/48082/48083/48087 由 nginx 承载、8090 由 bbb-web 承载、5060/8021 由 FreeSWITCH 承载、3478 由 coturn 承载

⚠️ 版本说明:BigBlueButton 官方主推裸机一键安装(4.0.0 对应 Ubuntu 24.04 + bbb-install-4.0.sh),bigbluebutton/docker 是官方 GitHub 组织下的社区编排项目,其 README 明确自述为「not official supported way」(非官方支持形态)。本文选择 Compose 形态的原因与 4.0 容器化边界(LiveKit 组件未覆盖)见《BigBlueButton 4.0.0 介绍与选型指南》第七章。

二、镜像选型说明

bigbluebutton/docker 不是「单镜像」项目,而是把 BBB 裸机安装拆成一组官方自建镜像的编排(全部镜像来自 Docker Hub alangecker/ 命名空间,与仓库内各服务目录的 Dockerfile 对应,版本由仓库 repos/tags 缓存文件钉住):

服务镜像/构建方式说明
bbb-webalangecker/bbb-docker-bbb-web(TAG_BBB=v3.0.39)BBB 核心(Grails API、会议管理)
freeswitch / webrtc-sfualangecker/bbb-docker-freeswitch、bbb-docker-webrtc-sfu语音混音与音视频转发(mediasoup)
nginx / haproxyalangecker/bbb-docker-nginx、alangecker/bbb-docker-haproxynginx 只在内网监听(48081/48082 走 proxy_protocol),TLS 终结由 haproxy 承担
greenlightbigbluebutton/greenlight:v3官方前端面板镜像
postgres / redispostgres:16、redis:6.2-alpineGreenlight 元数据 / BBB 消息与状态
etherpad 系列bbb-pads、bbb-export-annotations、bbb-shared-notes-server协作笔记与批注导出
coturnalangecker/bbb-docker-coturnTURN/STUN 中继
periodicalangecker/bbb-docker-periodic定时清理任务

镜像 tag 钉版机制(实测):仓库克隆后执行 ./scripts/generate-compose,脚本读取 repos/tags(实测内容为 bigbluebutton v3.0.39)与 .env,把 docker-compose.tmpl.yml 模板渲染为 docker-compose.yml。因此版本切换 = 修改 repos/tags 或检出对应分支后重新生成,不手动改 compose 文件。

三、前置条件

  • Ubuntu 22.04/24.04 服务器,root 权限,4 核 / 8 GB 内存以上(实测栈整机常驻内存约 2.5 GB,见 5.4 节);
  • Docker 24+ 与 Compose v2 插件;
  • 一个解析到服务器 IP 的域名(用于 HTTPS 证书与 Greenlight 房间链接);没有域名也可以按本文 4.3 节以「自签证书 + 关闭 Host 校验」的实验形态跑通;
  • 端口放行:TCP 80/443(Web 入口)、TCP/UDP 3478 与 UDP 49152-65535(coturn 中继)、UDP 16384-32768(WebRTC 媒体);
  • 服务器防火墙/安全组不得占用上述端口(haproxy 绑定 0.0.0.0:80/443)。

四、部署步骤

4.1 安装 Docker 并克隆编排仓库

# 安装 Docker(Ubuntu 24.04 实测回显)
apt-get update && apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
docker --version

实测回显:

Docker version 29.9.2, build 7c95437
git clone --depth 1 https://github.com/bigbluebutton/docker.git /opt/bbb-docker
cd /opt/bbb-docker
git log -1 --format="%H %cs"

实测回显:

e7571f4b3ed6e07c5cf6d7a0dea32f448432c94b 2026-10-18

4.2 编写 .env 并生成编排文件

从模板创建 .env(sample.env → .env),实测采用的核心内容如下(自签实验形态,SECRET 为实测生成的真实值):

ENABLE_HTTPS_PROXY=true
LETSENCRYPT_EMAIL=admin@example.com
ENABLE_GREENLIGHT=true
ENABLE_COLLABORA=false
ENABLE_COTURN=true
ENABLE_RECORDING=false
IGNORE_TLS_CERT_ERRORS=true
SHARED_SECRET=dQlqhNULhRDTwaPdKi2hXet1bihGeLqH0RDEXPOfEI
ETHERPAD_API_KEY=kE2mYvP8QrT4nW6bZ1xCj9Hs5aF0gLuD
RAILS_SECRET=Rt7Wq2ZkB9Xm4Nc6Vj1Pd8Hs3Fa0gLu5YeTr2Ow9Qk4
POSTGRESQL_SECRET=Pg9Xw4Rk2Zb8Nc5Vj1Md7Hs3Fa6gLu0
FSESL_PASSWORD=Fs8Xw3Rk6Zb9Nc4Vj2Pd7Hs5Fa1gLu
TURN_SECRET=Tn6Xw3Rk9Zb4Nc8Vj1Pd5Hs7Fa2gLu0
DOMAIN=bbb.example.com
EXTERNAL_IPv4=10.89.58.3
EXTERNAL_IPv6=
STUN_IP=216.93.246.18
STUN_PORT=3478
SIP_IP_ALLOWLIST=
DEFAULT_PRESENTATION=./mod/nginx/default.pdf
SOUNDS_LANGUAGE=en-us-callie
DISABLE_SOUND_MUTED=false
DISABLE_SOUND_ALONE=false
ENABLE_LEARNING_DASHBOARD=true
COMPOSE_PROJECT_NAME=bbb-3-0-39-stack

生成编排文件并启动:

cd /opt/bbb-docker
./scripts/generate-compose
docker compose up -d

实测要点:

  • generate-compose 借助临时辅助镜像把模板渲染为 docker-compose.yml(实测 455 行),.env 中 COMPOSE_PROJECT_NAME=bbb-3-0-39-stack 决定项目名——注意 Compose 项目名不允许点号,所以版本号 3.0.39 写作 3-0-39;
  • 首次 up -d 拉取镜像约需数分钟(全部镜像合计约 3 GB)。

4.3 确认服务状态(17 服务全 Up)

docker compose ps --format "{{.Name}}  {{.Status}}"

实测回显(按名称排序):

bbb-3-0-39-stack-apps-akka-1  Up 8 minutes
bbb-3-0-39-stack-bbb-export-annotations-1  Up 8 minutes
bbb-3-0-39-stack-bbb-graphql-actions-1  Up 8 minutes
bbb-3-0-39-stack-bbb-graphql-middleware-1  Up 8 minutes
bbb-3-0-39-stack-bbb-graphql-server-1  Up 8 minutes
bbb-3-0-39-stack-bbb-shared-notes-server-1  Up 7 minutes
bbb-3-0-39-stack-bbb-web-1  Up 8 minutes
bbb-3-0-39-stack-bbb-freeswitch-1  Up 8 minutes
bbb-3-0-39-stack-coturn-1  Up 8 minutes
bbb-3-0-39-stack-fsesl-akka-1  Up 8 minutes
bbb-3-0-39-stack-greenlight-1  Up 2 minutes
bbb-3-0-39-stack-haproxy-1  Up 8 minutes
bbb-3-0-39-stack-nginx-1  Up 8 minutes
bbb-3-0-39-stack-periodic-1  Up 8 minutes
bbb-3-0-39-stack-postgres-1  Up 8 minutes
bbb-3-0-39-stack-redis-1  Up 8 minutes
bbb-3-0-39-stack-webrtc-sfu-1  Up 8 minutes

⚠️ 实测踩坑:bbb-shared-notes-server 在首启时因 PostgreSQL 就绪竞态 Exited(2),等栈稳定后单独执行 docker compose up -d bbb-shared-notes-server 即恢复 Up,这是编排健康检查的已知竞态,不是故障。

4.4 创建 Greenlight 管理员

Greenlight v3 提供 rake 任务直接建管理员(无 SMTP 时的标准做法):

cd /opt/bbb-docker
docker compose exec -T greenlight bin/rake admin:create[root,root@example.com,q1w2E3r4!]

实测回显:

  Name: root
  Email: root@example.com
  Password: q1w2E3r4!
  Role: Administrator

(另以 admin:create[admin,admin@example.com,q1w2E3r4!] 同法创建了演示管理员 admin@example.com。)

⚠️ 实测踩坑:Greenlight 密码策略要求至少 8 位且同时包含大小写字母、数字与特殊字符,纯数字弱口令(如 q1w2e3r4)会被拒绝(报错 Password is invalid)。本文统一使用 q1w2E3r4!。

4.5 Web 入口验证(含 Blocked hosts 排障)

curl -sk -o /dev/null -w "%{http_code}\n" -H "Host: bbb.example.com" https://127.0.0.1/

首次实测返回 403,Greenlight 日志显示 Rails 的 HostAuthorization 拦截(实测日志行):

Blocked hosts: 127.0.0.1 AND bbb.example.com

原因与处置:IGNORE_TLS_CERT_ERRORS=true 的自签形态下,Greenlight 以内部 HTTP 端点(http://10.7.7.34:48083/bigbluebutton/api)访问 API,而其 Host 白名单来自 URL_HOST=https://bbb.example.com,自签实验形态下两种 Host 均不在白名单。Greenlight 官方预留了 BYPASS_HOST 环境变量,新增 docker-compose.override.yml 关闭 Host 校验(生产形态使用真实域名 + Let's Encrypt 证书时无需此步):

services:
  greenlight:
    environment:
      BYPASS_HOST: "true"

重建并复测:

docker compose up -d greenlight bbb-shared-notes-server
sleep 20
curl -sk -o /dev/null -w "greenlight -> %{http_code}\n" -H "Host: bbb.example.com" https://127.0.0.1/
curl -sk https://127.0.0.1/ -H "Host: bbb.example.com" | grep -oE "<title>[^<]+</title>"

实测回显:

greenlight -> 200
<title>BigBlueButton</title>

五、部署后验证

5.1 API 探活与校验和算法(重要)

BBB 3.0 起 HTTP API 的 checksum 拼接口径与 2.x 不同:新版为 sha256(action + queryString + sharedSecret),queryString 不含 checksum 参数本身。用 2.x 老口径(sha1(action + secret + queryString))调用带参数的 API 会返回 ChecksumError: checksum match error——但无参数的 getMeetings 恰好两种口径等价,容易误判。本专栏实测过程即被此坑误导(服务端日志打印的 SHA1 值与本地计算不一致,穷举比对后确认为拼接顺序变化)。

正确口径的 API 探活实测:

S=dQlqhNULhRDTwaPdKi2hXet1bihGeLqH0RDEXPOfEI
B=https://127.0.0.1/bigbluebutton/api
C=$(printf %s "getMeetings${S}" | sha256sum | cut -d" " -f1)
curl -sk "$B/getMeetings?checksum=$C"

实测回显:

<response>
<returncode>SUCCESS</returncode>
<meetings/>
<messageKey>noMeetings</messageKey>
<message>no meetings were found on this server</message>
</response>

5.2 create / getMeetingInfo / join / end 全链路实测

S=dQlqhNULhRDTwaPdKi2hXet1bihGeLqH0RDEXPOfEI
B=https://127.0.0.1/bigbluebutton/api
api(){ local a=$1 q=$2; local c=$(printf %s "${a}${q}${S}" | sha256sum | cut -d" " -f1); curl -sk --max-time 15 "${B}/${a}?${q}&checksum=${c}"; }
# create(显式指定两个会议密码)
Q="attendeePW=q1w2e3r4Att&meetingID=doc-test-002&moderatorPW=q1w2e3r4Mod&name=%E5%AE%9E%E6%B5%8B%E4%BC%9A%E8%AE%AE%E5%AE%A4&welcome=Welcome+to+doc-test"
api create "$Q" | grep -E "returncode|meetingID>|moderatorPW|attendeePW|createDateTime"
# getMeetingInfo
api getMeetingInfo "meetingID=doc-test-002" | grep -E "returncode|meetingName|moderatorPW|running"
# join(curl 跟随 302 前先看跳转)
J="fullName=%E6%B5%8B%E8%AF%95%E7%94%A8%E6%88%B7&meetingID=doc-test-002&password=q1w2e3r4Mod&redirect=true"
c=$(printf %s "join${J}${S}" | sha256sum | cut -d" " -f1)
curl -sk -o /dev/null -w "join -> HTTP %{http_code} Location=%{redirect_url}\n" "${B}/join?${J}&checksum=${c}"
# end
api end "meetingID=doc-test-002&password=q1w2e3r4Mod" | grep -E "returncode|sentEnd"

实测回显:

<response>
<returncode>SUCCESS</returncode>
<meetingID>doc-test-002</meetingID>
<internalMeetingID>5f363f9ed2ef17e9216b7adb9630e1780cd678f5-1793066362694</internalMeetingID>
<parentMeetingID>bbb-none</parentMeetingID>
<attendeePW>q1w2e3r4Att</attendeePW>
<moderatorPW>q1w2e3r4Mod</moderatorPW>
<createTime>1793066362694</createTime>
<voiceBridge>450178364</voiceBridge>
<dialNumber>613-555-1234</dialNumber>
<createDate>Tue Oct 27 01:59:22 UTC 2026</createDate>
<hasUserJoined>false</hasUserJoined>
<duration>0</duration>
<hasBeenForciblyEnded>false</hasBeenForciblyEnded>
<messageKey></messageKey>
<message></message>
</response>

getMeetingInfo 与 join、end 的实测回显:

<returncode>SUCCESS</returncode>
<meetingName>实测会议室</meetingName>
<moderatorPW>q1w2e3r4Mod</moderatorPW>
<running>false</running>
join -> HTTP 302 Location=https://bbb.example.com/html5client/?sessionToken=takeairlvrgibxkq
<returncode>SUCCESS</returncode>
<messageKey>sentEndMeetingRequest</messageKey>

join 返回 302 跳转至 html5client 会话页(sessionToken 为实测真实值),说明会议与客户端会话签发链路正常;把该 URL 在浏览器中打开即为入会页面。浏览器端音视频的实际体验(拾音/摄像/屏幕共享)依赖 TURN 与本地设备权限,无法以 curl 完成自动化验证,本文如实标注此边界。

5.3 getMeetings 复查(end 后会议移除)

api getMeetings "" | grep -E "returncode|messageKey|message" | head -3

实测回显:

<returncode>SUCCESS</returncode>
<messageKey>noMeetings</messageKey>
<message>no meetings were found on this server</message>

5.4 资源占用实测

docker stats --no-stream --format "{{.Name}}\t{{.MemUsage}}" | sort

实测回显(核心项):

bbb-3-0-39-stack-bbb-web-1        753.9MiB
bbb-3-0-39-stack-apps-akka-1      389.1MiB
bbb-3-0-39-stack-fsesl-akka-1     306.5MiB
bbb-3-0-39-stack-webrtc-sfu-1     306MiB
bbb-3-0-39-stack-greenlight-1     142.3MiB
bbb-3-0-39-stack-bbb-graphql-server-1  213.4MiB
bbb-3-0-39-stack-freeswitch        50.68MiB
bbb-3-0-39-stack-postgres-1        75.1MiB

17 个服务常驻内存合计约 2.4 GB(不含媒体转发峰值),8 GB 服务器即可承载轻量使用。

六、数据持久化说明

  • 持久化方式:bbb-docker 全部状态落在编排目录的 data/ 子目录(bind mount),实测 du -sh data/ 为 92M,包含 bigbluebutton/(会议状态)、postgres/(Greenlight 数据)、greenlight/、redis/、freeswitch-meetings/、coturn/、haproxy/(证书)、mediasoup/ 八个子目录;
  • 重建保数据实测:docker compose down && docker compose up -d 全栈销毁重建后,查询 Greenlight 用户表:
docker compose exec -T postgres psql -U postgres -d greenlight -t -c "select email from users;"

实测回显(down 前后各执行一次,结果一致):

 admin@example.com

即管理员账号与房间数据随 data/postgres/ 持久化,栈重建不丢失。注意:进行中的会议不跨重建保留(会议状态属运行时数据),end 后的录制产物路径与备份边界见《BigBlueButton 4.0.0 配置参数详解》第六章。

七、配置参数说明

  • .env 是唯一配置入口:生成编排后修改参数应改 .env 并重新执行 ./scripts/generate-compose + docker compose up -d(核心参数逐项解说与属性文件对照见《BigBlueButton 4.0.0 配置参数详解》);
  • 自签与正式证书:IGNORE_TLS_CERT_ERRORS=true 时 haproxy 启动脚本自签证书(实测证书 CN 为 DOMAIN 值);正式环境设为 false 并配置可达公网的 DOMAIN 与 LETSENCRYPT_EMAIL,由 haproxy 自动向 Let's Encrypt 申请;
  • BBB 共享密钥:.env 的 SHARED_SECRET 即 API checksum 密钥,与裸机形态的 bbb-conf --secret 输出同源(裸机形态解说见 CLI 命令篇)。

八、配置文件挂载

挂载说明
./data/全部持久化数据(postgres/redis/greenlight/haproxy 证书/会议状态)
./mod/nginx/default.pdf默认演示文稿(DEFAULT_PRESENTATION 指定)
./docker-compose.override.yml本文 4.5 节的 Greenlight 环境变量补充(BYPASS_HOST)

九、等价 docker run

BigBlueButton 是 17 个强耦合服务的编排栈(服务间通过固定编排网段 10.7.7.0/24 与宿主网络混合通信:bbb-web/freeswitch/webrtc-sfu 等使用 host 网络,nginx/greenlight 等使用编排网络固定 IP),逐服务手写等价 docker run 无实际运维价值,也极易错配环境注入。本文仅给出栈中结构最简单的 redis 服务的等价单命令(参数取自生成的 docker-compose.yml,仅作编排原理说明):

docker run -d --name redis \
  --network bbb-3-0-39-stack_bbb-net --ip 10.7.7.11 \
  -v /opt/bbb-docker/data/redis:/data \
  redis:6.2-alpine

⚠️ 该命令仅用于理解编排结构,请勿与 docker compose up -d 混用(同名网络/IP 冲突)。

十、常用运维命令

cd /opt/bbb-docker
docker compose ps                                   # 服务状态
docker compose logs -f bbb-web                      # 跟看 BBB 核心日志
docker compose restart bbb-web                      # 重启单个服务(改完 .env 后)
docker compose down && docker compose up -d         # 全栈重建(数据在 data/ 持久化)
docker compose exec -T postgres psql -U postgres -d greenlight -t -c "select email from users;"   # Greenlight 用户查询

十一、常见问题(FAQ)

Q1:API 调用报 ChecksumError: checksum match error? BBB 3.0 起校验和为 sha256(action + queryString + sharedSecret),不是 2.x 的 sha1(action + secret + queryString);无参数的 getMeetings 两者等价,带参数接口必须用新口径(见 5.1 节实测过程)。

Q2:Greenlight 页面 403,日志出现 Blocked hosts? Rails HostAuthorization 拦截了请求 Host。生产形态用真实域名 + Let's Encrypt 证书(IGNORE_TLS_CERT_ERRORS=false)即可匹配 URL_HOST;无域名的实验形态按 4.5 节加 BYPASS_HOST: "true"。

Q3:bbb-shared-notes-server 启动即退出? PostgreSQL 就绪竞态,docker compose up -d bbb-shared-notes-server 单独拉起即可(4.3 节实测)。

Q4:admin:create 报 Password is invalid? 密码需同时包含大小写字母、数字、特殊字符且 ≥8 位(4.4 节实测)。

Q5:能部署 BigBlueButton 4.0.0 吗? 截至 2026-10-27,bigbluebutton/docker 主线覆盖 3.0.39,4.0 的 LiveKit 媒体栈未纳入编排(README 自述 currently missing: livekit);4.0 请用官方裸机一键脚本(Ubuntu 24.04),见选型指南第七章。

Q6:TURN 中继通了吗? 本文实测范围内 coturn 服务 Up、TURN_SECRET 已注入并随栈启动;跨运营商/对称 NAT 场景下的外网中继连通性依赖公网安全组与证书,超出本文实测边界,如实标注未验证。

十二、k8s 形态简介

本专栏本批次以 Compose 形态实测交付;BigBlueButton 在 Kubernetes 上的部署形态现状如下(2026-10-27 官方文档实查,本篇未做 k8s 实测):

  • 官方未提供 k8s 编排:官方安装文档主线是裸机一键脚本,「Other installation options」章节列出的是社区维护的安装方式(Ansible 角色、含 Scalelite 的大规模 HA 方案等),未见官方 Helm chart 或官方 k8s 清单;
  • 官方规模化路径:多台裸机 BBB 服务器 + Scalelite 负载均衡器调度(官方另有 Cluster Proxy 集群代理方案文档),k8s 并非官方推荐的承载形态;
  • 社区 chart:第三方仓库存在以 Helm chart/清单形式编排 BBB 的尝试,成熟度与维护状态参差,采用前需自行评估(本文不列出未经实测验证的具体仓库);
  • 后续实测计划:k8s 形态(含社区 chart 可用性)由本专栏 K1 批次另行实测交付,本篇不实测 k8s。

十三、参考链接

  1. bigbluebutton/docker 编排仓库(README 含 .env 参数全集):https://github.com/bigbluebutton/docker
  2. sample.env 参数模板:https://github.com/bigbluebutton/docker/blob/master/sample.env
  3. BigBlueButton 官方文档(裸机安装对照):https://docs.bigbluebutton.org
  4. Greenlight 文档:https://docs.bigbluebutton.org/greenlight/overview
  5. 本专栏配套篇目:《BigBlueButton 4.0.0 介绍与选型指南》、《BigBlueButton 4.0.0 配置参数详解》、《BigBlueButton 4.0.0 常用 CLI 命令与工具详解》