Wazo Docker Compose 部署指南
Wazo Platform 组件级 Docker 镜像现状、自建微服务 Compose 栈(wazo-auth + wazo-confd + PostgreSQL + Redis + Asterisk)、生产边界说明与 Wazo C4 分支容器化路径
Wazo Docker Compose 部署指南
目标:说明 Wazo Platform 在容器化部署方面的现状——哪些组件有官方 Docker 镜像、如何把这些微服务拼装成一个用于开发和测试的 Compose 栈,并明确这种方案的适用边界。重要声明:Wazo Platform 目前没有官方一体化 Docker Compose 生产部署方案,也没有"docker run 一条命令启动完整 PBX"的镜像。本文所有 Compose 示例均用于开发调试和功能体验,生产环境请使用 《Debian 12 安装 Wazo Platform 指南》 的官方 Ansible 路线。
一、环境信息
- Wazo Platform 版本:26.10(2026-10-12 发布)
- Docker 要求:≥ 24.0
- Docker Compose 要求:v2(
docker compose命令,而非docker-compose) - 系统资源:建议 ≥ 4 GB RAM(PostgreSQL + Asterisk + 多个 Python 微服务)
- 可拉取的官方镜像:wazoplatform/wazo-auth、wazoplatform/wazo-plugind、wazoplatform/wazo-confd、wazoplatform/wazo-provd(其余服务需自建)
- 本文档内容基于 Wazo 官方文档与 Discourse 论坛整理(查询日期 2026-10-27)
二、Docker 镜像现状总览
2.1 官方维护的镜像
Wazo 在 Docker Hub(wazoplatform 账号)上维护了以下组件级镜像:
| 镜像名 | 服务 | 说明 |
|---|---|---|
wazoplatform/wazo-auth | 认证与鉴权 | 生产可用,暴露 :9497 |
wazoplatform/wazo-plugind | 插件管理 | 生产可用,暴露 :9503 |
wazoplatform/wazo-confd | 配置管理 | 开发/生产均可用,暴露 :9486 |
wazoplatform/wazo-provd | 话机自动配置 | 开发可用,暴露 :8667 |
拉取命令:
docker pull wazoplatform/wazo-auth:latest
docker pull wazoplatform/wazo-plugind:latest
docker pull wazoplatform/wazo-confd:latest
docker pull wazoplatform/wazo-provd:latest
2.2 没有官方镜像的核心组件
以下 Wazo 核心服务没有官方 Docker Hub 镜像:
| 服务 | 重要性 | 现状 |
|---|---|---|
asterisk | PBX 核心 | Debian 包 + Asterisk 源码,无官方镜像 |
wazo-calld | 呼叫控制 | 需从源码构建 |
wazo-amid | Asterisk AMI 桥接 | 需从源码构建 |
wazo-websocketd | 实时事件推送 | 需从源码构建 |
wazo-agid | Agent 网关 | 需从源码构建 |
wazo-confgend | 配置生成器 | 无独立端口,随 wazo-confd 一起安装 |
wazo-webhookd | Webhook 推送 | 需从源码构建 |
nginx | 反向代理 | 可用官方 nginx:alpine + 自定义配置 |
2.3 Wazo C4(Kamailio 分支)的 Compose 支持
Wazo 社区中有一个基于 Kamailio 的轻量级分支——Wazo C4(Wazo on Kamailio),它有官方的 Docker Compose 部署路径:
- Helm Chart:
github.com/wazo-platform/wazo-c4-helm - Docker Compose:
github.com/wazo-platform/wazo-kamailio-config
但 Wazo C4 是 Wazo Platform 的替代分支,不是"主平台的容器化版本"——它用 Kamailio 替代了 Asterisk,功能集有差异(缺少完整的 IVR、Queue ACD、Meeting 等基于 Asterisk 的高级特性)。如需 C4 部署请参考上述仓库,本文聚焦 Wazo Platform 主栈。
三、自建 Compose 栈(开发测试用)
⚠️ 本方案仅用于开发调试和功能预览,不要用于生产环境。生产环境必须用 《Debian 12 安装指南》 的 Ansible 路线。
3.1 架构说明
我们要拼装的最小可用微服务栈包含:
[wazo-auth] + [wazo-confd] + [PostgreSQL] + [Redis] + [Asterisk]
↓ ↓
Nginx 反代(统一 HTTPS 入口)
其中:
wazo-auth、wazo-confd直接用官方镜像PostgreSQL、Redis、Nginx用官方基础镜像 + 自定义配置Asterisk自建 Dockerfile(基于 Debian 12 Bookworm + Wazo 仓库的 asterisk 包)
3.2 准备工作目录
mkdir -p /opt/data/quzuo/tmp/wazo/docker-stack/{asterisk,nginx,config}
cd /opt/data/quzuo/tmp/wazo/docker-stack
3.3 Asterisk Dockerfile(自建)
cat <<'EOF' > asterisk/Dockerfile
# Wazo Platform 所需的 Asterisk 22 基础镜像(基于 Debian 12 Bookworm)
FROM debian:12-slim
ENV DEBIAN_FRONTEND=noninteractive
ENV WAZO_DISTRIBUTION=pelican-bookworm
# 安装基础工具
RUN apt-get update && apt-get install -yq ca-certificates curl gnupg sudo wget
# 添加 Wazo 官方仓库源(Bookworm + pelican-bookworm 生产稳定版)
RUN wget -q -O - https://mirror.wazo.community/key/repository.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/wazo.gpg \
&& echo "deb https://mirror.wazo.community/debian bookworm main" > /etc/apt/sources.list.d/wazo.list \
&& echo "deb https://mirror.wazo.community/debian pelican-bookworm main" >> /etc/apt/sources.list.d/wazo.list \
&& apt-get update
# 安装 Asterisk + 常用依赖
RUN apt-get install -yq \
asterisk asterisk-config asterisk-sounds-main asterisk-doc \
asterisk-modules asterisk-pjsip \
python3-pip python3-psycopg2 python3-yaml \
postgresql-client redis-tools \
&& rm -rf /var/lib/apt/lists/*
# 暴露 SIP / RTP 端口
EXPOSE 5060/udp 5061/tcp 4569/udp 49152-65535/udp
CMD ["/usr/sbin/asterisk", "-f"]
EOF
3.4 Nginx 配置
cat <<'EOF' > nginx/wazo.conf
server {
listen 80;
listen [::]:80;
server_name _;
# HTTP 自动跳转到 HTTPS(Compose 调试时可以注释掉)
# return 301 https://$host$request_uri;
# wazo-confd REST API
location /api/confd/ {
proxy_pass http://wazo-confd:9486/api/confd/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# wazo-auth REST API
location /api/auth/ {
proxy_pass http://wazo-auth:9497/api/auth/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# wazo-plugind REST API
location /api/plugind/ {
proxy_pass http://wazo-plugind:9503/api/plugind/;
proxy_set_header Host $host;
}
# Wazo WebSocket(用于 websocketd 实推)
location /ws/ {
proxy_pass http://wazo-websocketd:9502/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
EOF
3.5 Docker Compose 文件
cat <<'EOF' > docker-compose.yml
services:
# ============= 基础数据服务 =============
postgres:
image: postgres:16-bookworm
container_name: wazo-postgres-26
environment:
POSTGRES_DB: wazo
POSTGRES_USER: wazo
POSTGRES_PASSWORD: q1w2e3r4
volumes:
- ./data/postgres:/var/lib/postgresql/data
networks:
- wazo-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U wazo"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: wazo-redis-26
networks:
- wazo-net
# ============= 核心微服务(官方镜像) =============
wazo-auth:
image: wazoplatform/wazo-auth:latest
container_name: wazo-auth-26
environment:
XIVO_UUID: "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
DB_URI: "postgresql://wazo:q1w2e3r4@postgres:5432/wazo"
REDIS_URI: "redis://redis:6379/0"
WAZO_AUTH_HOST: "wazo-auth"
WAZO_AUTH_PORT: 9497
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
networks:
- wazo-net
expose:
- "9497"
wazo-confd:
image: wazoplatform/wazo-confd:latest
container_name: wazo-confd-26
environment:
XIVO_UUID: "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
DB_URI: "postgresql://wazo:q1w2e3r4@postgres:5432/wazo"
WAZO_AUTH_HOST: "wazo-auth"
WAZO_AUTH_PORT: 9497
WAZO_CONFD_PORT: 9486
depends_on:
- wazo-auth
- postgres
networks:
- wazo-net
expose:
- "9486"
wazo-plugind:
image: wazoplatform/wazo-plugind:latest
container_name: wazo-plugind-26
environment:
XIVO_UUID: "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
DB_URI: "postgresql://wazo:q1w2e3r4@postgres:5432/wazo"
WAZO_AUTH_HOST: "wazo-auth"
WAZO_AUTH_PORT: 9497
depends_on:
- wazo-auth
- postgres
networks:
- wazo-net
expose:
- "9503"
# ============= Asterisk(自建) =============
asterisk:
build:
context: ./asterisk
container_name: wazo-asterisk-26
environment:
ASTERISK_UUID: "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
# SIP + RTP 需要 host 网络或明确端口映射
network_mode: "host"
volumes:
- ./config/asterisk:/etc/asterisk/conf.d
- ./data/asterisk:/var/lib/asterisk
- ./data/asterisk-log:/var/log/asterisk
privileged: true
cap_add:
- SYS_PTRACE
- NET_ADMIN
# ============= Nginx 统一入口 =============
nginx:
image: nginx:alpine
container_name: wazo-nginx-26
ports:
- "8080:80"
- "8443:443"
volumes:
- ./nginx/wazo.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- wazo-auth
- wazo-confd
- wazo-plugind
networks:
- wazo-net
networks:
wazo-net:
driver: bridge
name: wazo-26-network
ipam:
config:
- subnet: 10.89.56.0/24
EOF
3.6 启动栈
cd /opt/data/quzuo/tmp/wazo/docker-stack
# 首次构建 Asterisk 镜像
docker compose build asterisk
# 启动所有服务
docker compose up -d
预期输出:
✔ Network wazo-26-network Created
✔ Container wazo-postgres-26 Started
✔ Container wazo-redis-26 Started
✔ Container wazo-auth-26 Started
✔ Container wazo-confd-26 Started
✔ Container wazo-plugind-26 Started
✔ Container wazo-asterisk-26 Started
✔ Container wazo-nginx-26 Started
3.7 验证
# 检查所有容器是否在运行
docker compose ps
# NAME STATUS
# wazo-postgres-26 Up 3 minutes (healthy)
# wazo-redis-26 Up 3 minutes
# wazo-auth-26 Up 2 minutes
# wazo-confd-26 Up 1 minute
# wazo-plugind-26 Up 1 minute
# wazo-asterisk-26 Up 1 minute
# wazo-nginx-26 Up 1 minute
# 测试 wazo-confd API(应该需要认证,返回 401 是正常的)
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/api/confd/1.1/users
# 401
# 测试 wazo-auth API
curl -s http://localhost:8080/api/auth/0.1/config | python3 -m json.tool
# {
# "external_api_address": "wazo-auth",
# "external_api_port": 9497,
# "token_expiration": 3600
# }
四、这种方案的局限性与风险
把 Wazo Platform 塞进 Docker Compose 有天然的适配问题:
4.1 服务间依赖不完整
Wazo 各微服务之间有内部 HTTP/RabbitMQ 调用,不是简单的"启动顺序"能解决的:
wazo-confd启动时需要数据库表结构已初始化(由xivo-dao迁移脚本完成)wazo-auth需要xivo-dao迁移 + 初始 admin 用户种子数据wazo-calld依赖 Asterisk 已启动并正确加载 PJSIPwazo-confgend生成 Asterisk 配置,要求 Asterisk 包和模板文件在同一容器
Ansible Playbook 会自动处理这些(数据库迁移、种子数据、Asterisk 模块启用),但自建 Compose 栈要手动补齐。
4.2 SIP / RTP 网络问题
Asterisk 容器需要:
- UDP 5060 / 5061 — SIP 信令
- UDP 49152-65535 — RTP 媒体流
用 bridge 网络时这些端口需要显式映射 + host.docker.internal NAT 穿透配置。最简单的办法是 network_mode: host(见上面的 Compose 示例),但这意味着:
- 容器会占用宿主机端口,多实例冲突
- 失去了隔离
4.3 数据库迁移脚本缺失
xivo-dao(PostgreSQL schema + 种子数据)不在任何 wazoplatform Docker Hub 镜像里。你需要自己执行:
# 在 postgres 容器里执行
docker exec -it wazo-postgres-26 bash -c 'apt-get update && apt-get install -y python3-pip && pip install wazo-dao && wazo-dao-upgrade postgresql://wazo:q1w2e3r4@localhost:5432/wazo head'
没有执行过数据库迁移的话,wazo-confd / wazo-auth 启动后会立即退出(找不到必须的表结构)。
4.4 没有完整的生产托管
- 进程管理:systemd 保证每个 Wazo 服务崩溃后自动重启;Docker Compose 的
restart: always可以替代,但没 systemd 精细 - 监控 / zabbix agent:Ansible 会自动安装,自建 Compose 需要额外部署
- 日志轮转:Wazo 默认配置 logrotate,容器里需要自己配
- SIP NAT / firewall:生产环境通常需要 nftables + 明确的 externaddr 配置,容器里更复杂
五、生产部署选型建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 生产 PBX(20+ 分机) | ✅ Ansible Playbook on Debian 12 | 唯一官方支持,完整功能,运维顺畅 |
| 开发调试 REST API / WebSocket | ✅ 自建 Compose(本文方案) | 快速起停、日志集中、API 端点直连 |
| 功能预览 / 概念验证 | ✅ 自建 Compose 或 Ansible 临时机 | 15 分钟内跑起来、体验 API |
| Wazo C4(Kamailio 分支) | ✅ 官方 Helm Chart / Compose | Wazo C4 原生支持容器化 |
| 不想用 Debian 12 | ❌ 自行移植风险高 | 官方只保证 Bookworm,其他发行版自行负责 |
六、清理 Compose 栈
# 停止并删除所有容器 + 网络
cd /opt/data/quzuo/tmp/wazo/docker-stack
docker compose down
# 连同数据卷一起清空(⚠️ 会删除所有数据库和配置)
docker compose down -v
rm -rf data/ config/
七、等价 docker run 命令
如果你不用 Compose,以下是等价的 docker run 示例(仅 wazo-auth):
# 启动 wazo-auth(前提:PostgreSQL 和 Redis 已在运行)
docker run -d \
--name wazo-auth-standalone \
--network host \
-e "XIVO_UUID=a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" \
-e "DB_URI=postgresql://wazo:q1w2e3r4@localhost:5432/wazo" \
-e "REDIS_URI=redis://localhost:6379/0" \
wazoplatform/wazo-auth:latest
# 查看日志
docker logs -f wazo-auth-standalone
# 停止并删除
docker stop wazo-auth-standalone && docker rm wazo-auth-standalone
八、常见问题(FAQ)
Q1: wazo-confd 容器启动报错 "Database migration pending"?
原因:PostgreSQL 还没执行 xivo-dao 迁移脚本。
解决:进入 PostgreSQL 容器手动执行:
docker compose exec postgres apt-get update -y \
&& docker compose exec postgres apt-get install -y python3-pip \
&& docker compose exec postgres pip install xivo-dao \
&& docker compose exec postgres wazo-dao-upgrade \
'postgresql://wazo:q1w2e3r4@localhost:5432/wazo' head
Q2: wazo-auth 日志里报错 "Failed to connect to PostgreSQL"?
排查:
- PostgreSQL 容器是否在运行?
docker compose ps确认状态是 Up / healthy DB_URI里的主机名是否是 compose 网络里的 service name(本文用postgres),不是localhost- 网络是否是同一个?
docker network inspect wazo-26-network看所有服务的容器都在里面
Q3: 从话机注册 SIP 时注册不上?
原因:Asterisk 容器用 network_mode: host 时,宿主机上不能同时有占用 5060 端口的服务(如 bind9、旧 Asterisk 安装)。
解决:
- 检查宿主机端口占用:
ss -ulnp | grep 5060 - 停掉宿主机上可能冲突的服务
- 如果用 bridge 网络而非 host 网络,需要
-p 5060:5060/udp -p 49152-65535:49152-65535/udp显式映射
Q4: 官方什么时候会出一体化的 Wazo Docker Compose?
根据 Wazo 社区 Discourse 讨论(2025-09 "Wazo with Docker" topic),Wazo Platform 短期不打算提供完整 Compose——原因是 Asterisk + PostgreSQL + 10+ Python 微服务的组件化边界还在调整中,容器化优先级低于 Debian Bookworm 迁移和日常功能迭代。当前的容器镜像仅供开发者跑集成测试和构建 Debian 包使用。
九、参考链接
| 链接 | 说明 |
|---|---|
| https://github.com/wazo-platform/wazo-confd/tree/master/contribs/docker | wazo-confd 官方 Dockerfile |
| https://wazo-platform.org/uc-doc/contributors/integration-tests/ | Wazo 集成测试(用 Docker Compose 跑测试用例) |
| https://hub.docker.com/u/wazoplatform | Docker Hub wazoplatform 账号 |
| https://wazo-platform.discourse.group/t/wazo-with-docker/105 | "Wazo with Docker" Discourse 主题(官方回复) |
| https://github.com/wazo-platform/wazo-c4-helm | Wazo C4(Kamailio 分支)Helm Chart |
| https://github.com/wazo-platform/wazo-kamailio-config | Wazo C4 Docker Compose 配置 |
| https://www.quzuo.net/document/6ijNclQUrvYh | 本平台 Wazo Debian 12 官方安装指南 |