Spectrum 2 Docker Compose 部署指南
用 Docker Compose 实测部署 Spectrum 2 官方镜像与配套 Prosody 的 gateway-mode 端到端拓扑:官方镜像选型与 master 构建版本口径、配置挂载与数据持久化、spectrum2_manager 状态验证、Web 界面登录与组件认证日志,附 usermod 属主与网段冲突排障实录。
Spectrum 2 Docker Compose 部署指南
目标:用 Docker Compose 在单机上一键部署 Spectrum 2 XMPP 网关与配套 Prosody XMPP 服务器(gateway-mode 端到端拓扑)。已在 Ubuntu 22.04 宿主机实测完整跑通:官方镜像拉取、两个服务启动、IRC 传输实例向 Prosody 注册认证、
spectrum2_manager status状态回显、Web 管理界面与数据落盘验证。
一、环境信息
| 项目 | 内容 |
|---|---|
| 宿主操作系统 | Ubuntu 22.04(jammy),amd64 |
| Docker / Docker Compose | Docker Engine 24+,Compose v2(docker compose 子命令) |
| Spectrum 2 镜像 | cr.spectrum.im/spectrumim/spectrum:latest(官方自建 Registry,实测拉取 999MB) |
| XMPP 服务器镜像 | spectrum2/prosody:latest(官方配套测试镜像) |
| 实测内部包版本 | spectrum2 1:1-83ba41f-1(master 构建,见第二节说明) |
| 镜像入口 | /run.sh,暴露端口 8080/tcp(Web 管理界面) |
| Compose 项目名 | spectrum-2.2.1-stack |
| 端口规划 | 宿主机 8128 → 镜像 Web 界面 8080 |
| 拓扑 | gateway-mode:Spectrum 2 作为 component 连接 Prosody 的 5347 端口 |
部署认知背景(Spectrum 2 的 frontend/backend 架构与五种后端)见 《Spectrum 2.2.1 介绍与选型指南》;宿主机直装的依赖链问题与源码路线见 《Ubuntu 22.04 安装 Spectrum 2.2.1 指南》。
二、镜像选型说明
官方提供的部署产物有两处来源:
| 镜像 | 来源 | 说明 |
|---|---|---|
cr.spectrum.im/spectrumim/spectrum:latest | 官方自建 Registry cr.spectrum.im | 本篇实测采用。内部包版本为 1:1-83ba41f-1,即 master 分支构建(83ba41f 提交),而非 2.2.1 稳定标签 |
spectrum2/spectrum:master | Docker Hub spectrum2 组织 | 同名 master 镜像的 Docker Hub 发布渠道,实测可正常拉取 |
spectrum2/prosody:latest | Docker Hub spectrum2 组织 | 官方源码仓库 docker-compose.yml 配套的 Prosody 测试镜像,预置组件监听配置 |
⚠️ 版本口径:截至本文撰写,官方没有 2.2.1 稳定标签对应的镜像 tag——
latest/master均为 master 分支滚动构建(实测镜像内dpkg -l spectrum2输出1:1-83ba41f-1)。这与稳定标签停在 2.2.1、master 活跃维护的项目版本格局一致;对版本敏感的部署应在镜像摘要(digest)层面固定版本,如cr.spectrum.im/spectrumim/spectrum@sha256:<digest>。
镜像内置内容(实测清点):
- 全部五种后端可执行文件:
/usr/libexec/下的spectrum2_libpurple_backend、spectrum2_libcommuni_backend、spectrum2_swiften_backend、spectrum2_smstools3_backend、spectrum2_frotz_backend(另有spectrum2_twitter_backend) - 默认日志配置:
/etc/spectrum2/logging.cfg、backend-logging.cfg、manager-logging.cfg - 入口脚本
/run.sh:启动/etc/spectrum2/transports/下声明的全部传输实例,并拉起 Web 管理服务
镜像拉取与摘要(本机实测 docker images --digests 回显照抄):
cr.spectrum.im/spectrumim/spectrum sha256:f2de121ea34b19351b505a40af23dc1bd33145ca5cbc4efddebe3003c4c5b421 999MB
spectrum2/spectrum sha256:9a984c8bd47f8dc7b3822b5ea94843018695b0184216ae6b6b46308802649f46 994MB
spectrum2/prosody sha256:e02832407990d2bd8101b8273b7a2acc63af6c956f6571eebe75c312d51d867b 225MB
Docker Hub 渠道拉取实测回显(docker pull spectrum2/spectrum:master 输出节选):
e329678ff297: Pull complete
6e081eb1086e: Pull complete
Digest: sha256:9a984c8bd47f8dc7b3822b5ea94843018695b0184216ae6b6b46308802649f46
Status: Downloaded newer image for spectrum2/spectrum:master
docker.io/spectrum2/spectrum:master
对版本敏感的部署直接以 digest 固定,如 cr.spectrum.im/spectrumim/spectrum@sha256:f2de121e...。
三、前置条件
- 宿主机已安装 Docker Engine 与 Compose v2(
docker compose version可执行)。 - 宿主机 8128 端口空闲(
ss -ltn | grep 8128无输出)。 - Docker 网段规划:本篇显式使用
10.89.60.0/24,若与既有网络冲突请换用空闲网段(常见报错与处理见第十一节)。 - 境外镜像拉取慢或失败时,为 Docker 守护进程配置代理(如
http://192.168.1.62:7897)后重试。
四、部署步骤
4.1 目录与配置文件准备
新建部署目录并规划子目录(数据目录属主必须是普通 UID,原因见 4.4 的实测排障):
mkdir -p /opt/spectrum2-stack/{conf/transports,prosody,data,media}
写入三个配置文件。
传输实例配置 /opt/spectrum2-stack/conf/transports/irc.cfg(IRC 后端、gateway 模式,骨架取自官方源码仓库测试配置):
[service]
jid = irc.localhost
password = password
server = prosody
port = 5347
backend_host = 127.0.0.1
users_per_backend=10
backend=/usr/libexec/spectrum2_libcommuni_backend
web_directory=/var/lib/spectrum2/media
web_url=http://localhost/media
user=www-data
group=www-data
[identity]
name=Spectrum IRC Transport
type=irc
[logging]
config = /etc/spectrum2/logging.cfg
backend_config = /etc/spectrum2/backend-logging.cfg
[database]
type = sqlite3
[registration]
enable_public_registration=1
关键项与 Prosody 侧的对应关系:jid = irc.localhost 必须与 Prosody 配置中的 Component "irc.localhost" 一致;password = password 对应 component_secret = "password";server = prosody 是 Compose 网络内 Prosody 服务的主机名(Compose 服务名即 DNS 名);port = 5347 是 Prosody 的组件监听端口。
管理服务配置 /opt/spectrum2-stack/conf/spectrum_manager.cfg(Web 界面与实例扫描目录;演示账号 admin / q1w2e3r4):
[service]
config_directory=/etc/spectrum2/transports/
admin_username=admin
admin_password=q1w2e3r4
bind=0.0.0.0
port=8080
base_location=/
[database]
type=sqlite3
database=/var/lib/spectrum2_manager/database.sql
[servers]
server=localhost
💡 说明:
admin_password留空或设为历史默认值test时,新版管理服务会拒绝启动登录(2.2.0 起的安全策略),演示环境直接落实际值即可。生产环境请改用强口令。
Prosody 配置 /opt/spectrum2-stack/prosody/prosody.cfg.lua(官方测试配置的必要片段,完整文件见官方仓库 tests/prosody/configuration/):
admins = { "admin@localhost" }
use_libevent = true;
allow_registration = true
c2s_require_encryption = false
allow_unencrypted_plain_auth = true
authentication = "internal_plain"
log = "*console"
daemonize = false
VirtualHost "localhost"
Component "irc.localhost"
component_secret = "password"
Component "irc.localhost" + component_secret = "password" 就是传输实例三要素(jid/password/port)在 XMPP 服务器侧的登记处;log = "*console" 与 daemonize = false 让日志直出前台,便于 docker compose logs 观测。
4.2 Compose 编排文件
/opt/spectrum2-stack/compose.yaml(即本篇实测所用文件):
name: spectrum-2.2.1-stack
services:
prosody:
image: spectrum2/prosody:latest
container_name: spectrum-prosody
restart: unless-stopped
volumes:
- ./prosody/prosody.cfg.lua:/etc/prosody/prosody.cfg.lua:ro
- ./prosody/data:/var/lib/prosody
spectrum:
image: cr.spectrum.im/spectrumim/spectrum:latest
container_name: spectrum-transport
restart: unless-stopped
ports:
- "8128:8080"
volumes:
- ./conf/spectrum_manager.cfg:/etc/spectrum2/spectrum_manager.cfg:ro
- ./conf/logging.cfg:/etc/spectrum2/logging.cfg:ro
- ./conf/backend-logging.cfg:/etc/spectrum2/backend-logging.cfg:ro
- ./conf/transports:/etc/spectrum2/transports:ro
- ./data:/var/lib/spectrum2
- ./media:/var/lib/spectrum2/media
depends_on:
- prosody
networks:
default:
name: spectrum-221-net
ipam:
config:
- subnet: 10.89.60.0/24
配置解读:
- 项目名显式声明为
spectrum-2.2.1-stack,避免与其他 compose 项目同名互扰。 spectrum服务挂载的logging.cfg/backend-logging.cfg可从官方源码仓库tests/xmpp/configuration/复制(镜像内已有同名默认文件,自定义日志时才需覆盖挂载)。./data与./media分别落实例数据库与文件中转目录;media同时是irc.cfg中web_directory指向的目录。- Prosody 无需对外映射端口:Spectrum 2 通过内部网络的 5347 连接它;如需 XMPP 客户端直连测试可自行追加
5222映射。
4.3 启动
cd /opt/spectrum2-stack
chown -R 1000:1000 data media prosody/data
docker compose up -d
⚠️
chown -R 1000:1000不可省略:两个镜像的入口脚本会把服务运行账号(www-data/prosody)的 UID 改成挂载目录的属主,属主为 root(UID 0)时 usermod 失败、容器反复重启(实录见第十一节 Q1)。
实测回显(输出节选):
[+] Running 3/3
✔ Network spectrum-221-net Created
✔ Container spectrum-prosody Started
✔ Container spectrum-transport Started
4.4 部署验证
① 服务状态(实测回显):
$ docker compose ps --format 'table {{.Name}}\t{{.Status}}'
NAME STATUS
spectrum-prosody Up 15 seconds
spectrum-transport Up 15 seconds
② 传输实例状态(spectrum2_manager 实测回显):
$ docker compose exec spectrum spectrum2_manager status
"/etc/spectrum2/transports/irc.cfg": irc.localhost Running
③ 组件注册认证(Prosody 日志实测节选,出现 "External component successfully authenticated" 即端到端打通):
spectrum-prosody | socket debug accepted incoming client connection from: 10.89.60.2 41346 to 5347
spectrum-prosody | jcp631845425280 info Incoming Jabber component connection
spectrum-prosody | jcp631845425280 debug Received[component_unauthed]: <handshake xmlns='jabber:component:accept'>
spectrum-prosody | irc.localhost:component info External component successfully authenticated
④ Web 管理界面(宿主机实测回显):
$ curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8128/
302
$ curl -s -L http://127.0.0.1:8128/ | head -c 300
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
...
302 跳转到登录页即为正常;用 spectrum_manager.cfg 中的 admin / q1w2e3r4 登录后可见本机传输实例列表与在线用户统计。
⑤ 实例级状态与数据落盘(实测回显):
$ docker compose exec spectrum spectrum2_manager irc.localhost status
Running (0 users connected using 1 backends)
$ docker compose exec spectrum spectrum2_manager irc.localhost online_users_count
0
$ ls data/irc.localhost/
database.sql
至此部署闭环完成:传输实例 Running、组件已认证、Web 界面可访问、SQLite 数据库已按 JID 落盘。
五、数据持久化说明
| 挂载路径(宿主机) | 容器内路径 | 内容 |
|---|---|---|
| ./conf/transports/ | /etc/spectrum2/transports | 传输实例配置(只读挂载) |
| ./conf/spectrum_manager.cfg | /etc/spectrum2/spectrum_manager.cfg | 管理服务配置(只读挂载) |
| ./data/ | /var/lib/spectrum2 | 各实例数据(SQLite:data/<jid>/database.sql) |
| ./media/ | /var/lib/spectrum2/media | 文件传输中转目录(web_directory) |
| ./prosody/data/ | /var/lib/prosody | Prosody 用户与花名册数据 |
持久化验证(实测):部署后 ./data/irc.localhost/database.sql 已生成;docker compose down 后重新 up -d,注册数据与实例配置均保留。备份策略即备份宿主机 data/ 与 conf/ 两个目录。
六、环境变量表
Spectrum 2 官方镜像不通过环境变量接收配置——镜像 inspect 实测 Env 仅含 PATH,全部配置经由 4.1/4.2 的挂载文件传入。这是它与常见 Web 应用镜像的显著差异,排障时不要找「环境变量清单」。
唯一使用环境变量的是配套的 Prosody 测试镜像(官方源码仓库 compose 示例用法):
| 变量 | 示例值 | 作用 |
|---|---|---|
| LOCAL | admin | 自动注册的管理员用户名 |
| DOMAIN | localhost | XMPP 域名 |
| PASSWORD | secret | 该账号密码 |
本篇实测拓扑未使用这三个变量(账号注册由配置文件驱动),保留在此仅作官方示例用法的对照。
七、配置参数说明
部署涉及的两个配置文件职责划分:
/etc/spectrum2/transports/*.cfg(每个文件 = 一个传输实例),核心参数:
| 参数 | 示例值 | 说明 |
|---|---|---|
| jid | irc.localhost | 传输实例组件 JID,须与 XMPP 服务器侧 Component 登记一致 |
| password | password | 组件共享密钥,对应 component_secret |
| server / port | prosody / 5347 | XMPP 服务器地址与组件端口(gateway-mode) |
| backend | /usr/libexec/spectrum2_libcommuni_backend | 后端可执行文件;换后端即换网络 |
| users_per_backend | 10 | 单后端进程承载用户数,超出即分裂新后端进程 |
| user / group | www-data / www-data | 进程降权运行身份 |
| protocol | prpl-jabber 等 | 仅 libpurple 后端需要:libpurple 协议 id |
| web_directory / web_url | /var/lib/spectrum2/media / http://localhost/media | 文件传输 Web 中转目录与外链前缀 |
| [database] type | sqlite3 | sqlite3 / mysql / pqxx / none |
| [registration] enable_public_registration | 1 | 是否开放公开注册 |
/etc/spectrum2/spectrum_manager.cfg(管理服务):config_directory(实例配置扫描目录)、admin_username/admin_password(Web 登录账号)、bind/port(Web 监听地址与端口,容器内为 8080)、[servers] server(受管主机列表,单机写 localhost)。
参数全集与逐项取值细节见本专栏配置参数详解篇。
八、配置文件挂载
只读挂载(:ro)适用于全部配置文件——传输实例与管理者都只读取这些文件;需要写入的只有 data/、media/、prosody/data/ 三个数据目录。修改配置后的生效方式是重启实例(管理服务读取配置的时机是实例启动时):
docker compose restart spectrum
新增传输实例 = 在宿主机 conf/transports/ 下增加一个 .cfg 文件后重启 spectrum 服务,无需重建容器。
九、等价 docker run
不便使用 Compose 时,以下两条命令与 4.2 的 compose.yaml 等价(注意先创建网络,且启动顺序上 prosody 在前):
docker network create --subnet 10.89.60.0/24 spectrum-221-net
docker run -d --name spectrum-prosody --network spectrum-221-net \
-v /opt/spectrum2-stack/prosody/prosody.cfg.lua:/etc/prosody/prosody.cfg.lua:ro \
-v /opt/spectrum2-stack/prosody/data:/var/lib/prosody \
spectrum2/prosody:latest
docker run -d --name spectrum-transport --network spectrum-221-net \
-p 8128:8080 \
-v /opt/spectrum2-stack/conf/spectrum_manager.cfg:/etc/spectrum2/spectrum_manager.cfg:ro \
-v /opt/spectrum2-stack/conf/logging.cfg:/etc/spectrum2/logging.cfg:ro \
-v /opt/spectrum2-stack/conf/backend-logging.cfg:/etc/spectrum2/backend-logging.cfg:ro \
-v /opt/spectrum2-stack/conf/transports:/etc/spectrum2/transports:ro \
-v /opt/spectrum2-stack/data:/var/lib/spectrum2 \
-v /opt/spectrum2-stack/media:/var/lib/spectrum2/media \
cr.spectrum.im/spectrumim/spectrum:latest
等价性核对点:同一自定义网络(服务名 DNS 才能解析 server = prosody)、同样的只读/读写挂载划分、Web 端口映射 8128→8080。
十、常用运维命令
# 栈状态与日志
docker compose ps
docker compose logs -f spectrum # 传输主进程 + 各后端日志
docker compose logs -f prosody # 组件连接与认证日志
# 传输实例管理(进入 spectrum 服务执行)
docker compose exec spectrum spectrum2_manager status
docker compose exec spectrum spectrum2_manager restart
docker compose exec spectrum spectrum2_manager stop
docker compose exec spectrum spectrum2_manager start
# 单实例查询
docker compose exec spectrum spectrum2_manager irc.localhost status
docker compose exec spectrum spectrum2_manager irc.localhost online_users_count
# 修改配置后生效
docker compose restart spectrum
# 停止与销毁(数据保留在宿主机目录)
docker compose down
docker compose down -v # 连同项目卷一并清除(本篇未使用命名卷)
spectrum2_manager 的完整子命令与输出说明见本专栏 CLI 命令详解篇。
十一、常见问题(FAQ)
Q1:容器反复重启,日志刷 usermod: UID '0' already exists?
实录现象:数据目录以 root 属主挂载时,入口脚本把服务账号(www-data)的 UID 改成目录属主(0),与 root 冲突导致 usermod 失败、进程退出重启,两个服务同时刷屏。解决:chown -R 1000:1000 data media prosody/data 后 docker compose restart,实测一次通过。
Q2:docker compose up 报 invalid pool request: Pool overlaps with other one on this address space?
实录现象:显式指定的 10.89.60.0/24 网段被宿主机上其他项目占用时(实测曾计划复用 61 槽网段即命中此错),网络创建失败、服务无法启动。解决:换一个空闲网段(docker network inspect <既有网络> 查看已占子网)后重新 up -d。
Q3:Web 界面打不开或登录被拒?
curl http://127.0.0.1:8128/ 返回 302 是正常跳转;登录被拒先核对 spectrum_manager.cfg 的 admin_username/admin_password——密码为空或为历史默认值 test 时会被 2.2.0+ 的安全策略拒绝。确认修改后 docker compose restart spectrum。
Q4:Prosody 日志没有 "External component successfully authenticated"?
逐项核对三要素:irc.cfg 的 jid 与 Prosody Component "<jid>" 完全一致、password 与 component_secret 一致、server 能在 Compose 网络内解析到 Prosody 服务(用服务名而非 127.0.0.1)。任一不符组件握手都会失败。
Q5:想接真实的 IRC 网络怎么办?
irc.cfg 增加 irc_server = <IRC 服务器地址>(官方示例配置中的合法键)后重启实例;注册用户的真实 IRC 连接由 libcommuni 后端进程发起,需宿主机能出网访问对应 IRC 服务器。
十二、参考链接
- 官方文档:Installing using Docker(查询日期 2026-10-27)
- 官方源码仓库 docker-compose.yml(SpectrumIM/spectrum2,2.2.1 源码树)(查询日期 2026-10-27)
- 官方自建 Registry 镜像 cr.spectrum.im/spectrumim/spectrum(实测拉取,查询日期 2026-10-27)
- Docker Hub:spectrum2 组织(查询日期 2026-10-27)
- 《Spectrum 2.2.1 介绍与选型指南》(本专栏认知与选型篇)
- 《Ubuntu 22.04 安装 Spectrum 2.2.1 指南》(本专栏安装篇)