Spectrum 2 Docker Compose 部署指南

用 Docker Compose 实测部署 Spectrum 2 官方镜像与配套 Prosody 的 gateway-mode 端到端拓扑:官方镜像选型与 master 构建版本口径、配置挂载与数据持久化、spectrum2_manager 状态验证、Web 界面登录与组件认证日志,附 usermod 属主与网段冲突排障实录。

Spectrum 2XMPPJabber/XMPP即时通讯Spectrum 22026/10/27

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 ComposeDocker 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:masterDocker Hub spectrum2 组织同名 master 镜像的 Docker Hub 发布渠道,实测可正常拉取
spectrum2/prosody:latestDocker 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...。

三、前置条件

  1. 宿主机已安装 Docker Engine 与 Compose v2(docker compose version 可执行)。
  2. 宿主机 8128 端口空闲(ss -ltn | grep 8128 无输出)。
  3. Docker 网段规划:本篇显式使用 10.89.60.0/24,若与既有网络冲突请换用空闲网段(常见报错与处理见第十一节)。
  4. 境外镜像拉取慢或失败时,为 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/prosodyProsody 用户与花名册数据

持久化验证(实测):部署后 ./data/irc.localhost/database.sql 已生成;docker compose down 后重新 up -d,注册数据与实例配置均保留。备份策略即备份宿主机 data/ 与 conf/ 两个目录。

六、环境变量表

Spectrum 2 官方镜像不通过环境变量接收配置——镜像 inspect 实测 Env 仅含 PATH,全部配置经由 4.1/4.2 的挂载文件传入。这是它与常见 Web 应用镜像的显著差异,排障时不要找「环境变量清单」。

唯一使用环境变量的是配套的 Prosody 测试镜像(官方源码仓库 compose 示例用法):

变量示例值作用
LOCALadmin自动注册的管理员用户名
DOMAINlocalhostXMPP 域名
PASSWORDsecret该账号密码

本篇实测拓扑未使用这三个变量(账号注册由配置文件驱动),保留在此仅作官方示例用法的对照。

七、配置参数说明

部署涉及的两个配置文件职责划分:

/etc/spectrum2/transports/*.cfg(每个文件 = 一个传输实例),核心参数:

参数示例值说明
jidirc.localhost传输实例组件 JID,须与 XMPP 服务器侧 Component 登记一致
passwordpassword组件共享密钥,对应 component_secret
server / portprosody / 5347XMPP 服务器地址与组件端口(gateway-mode)
backend/usr/libexec/spectrum2_libcommuni_backend后端可执行文件;换后端即换网络
users_per_backend10单后端进程承载用户数,超出即分裂新后端进程
user / groupwww-data / www-data进程降权运行身份
protocolprpl-jabber 等仅 libpurple 后端需要:libpurple 协议 id
web_directory / web_url/var/lib/spectrum2/media / http://localhost/media文件传输 Web 中转目录与外链前缀
[database] typesqlite3sqlite3 / mysql / pqxx / none
[registration] enable_public_registration1是否开放公开注册

/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 服务器。

十二、参考链接

  1. 官方文档:Installing using Docker(查询日期 2026-10-27)
  2. 官方源码仓库 docker-compose.yml(SpectrumIM/spectrum2,2.2.1 源码树)(查询日期 2026-10-27)
  3. 官方自建 Registry 镜像 cr.spectrum.im/spectrumim/spectrum(实测拉取,查询日期 2026-10-27)
  4. Docker Hub:spectrum2 组织(查询日期 2026-10-27)
  5. 《Spectrum 2.2.1 介绍与选型指南》(本专栏认知与选型篇)
  6. 《Ubuntu 22.04 安装 Spectrum 2.2.1 指南》(本专栏安装篇)