Converse.js 14.0.1 Docker Compose 部署指南

用 Docker Compose 部署 Converse.js 14.0.1:官方无镜像,给 20 行多阶段 Dockerfile 自建(node:22-slim 取 npm 产物 + nginx:alpine 托管),config.js 挂载注入改配置免重建,含全部实测回显与 FAQ。

Converse.jsConverse.jsXMPPDockerDocker Compose自托管2026/10/25

Converse.js 14.0.1 Docker Compose 部署指南

目标:用 Docker Compose 一键部署 Converse.js 14.0.1 Web 聊天站——由于官方不发布镜像,本文给出 20 行多阶段 Dockerfile 自建镜像(构建期 node:22-slim 取 npm 产物、运行期 nginx:alpine 托管),运行期配置经 bind mount 注入、改配置免重建镜像。已在 Docker 29.9.2 + Compose v5.6.1 实测通过(镜像 121MB,容器运行中验证)。

一、环境信息

本文所有命令与回显均在以下实测环境中执行:

  • Docker:29.9.2;Docker Compose:v5.6.1
  • 自建镜像:conversejs:14.0.1(121MB;构建阶段基座 node:22-slim,运行阶段基座 nginx:alpine,nginx/1.31.8)
  • Converse.js:14.0.1(npm 包 converse.js)
  • Compose 项目名:conversejs-14.0.1-stack;容器名:conversejs-14.0.1-web
  • 端口映射:宿主 8132 → 容器 80;项目网络:conversejs-net(10.89.72.0/24)
  • 项目目录:/opt/conversejs/(Dockerfile、nginx.conf、index.html、config.js、docker-compose.yml 五个文件)
  • 验证浏览器:Chromium(无头模式,CDP 驱动检查 DOM 与配置注入)

二、镜像选型说明

Converse.js 没有官方 Docker 镜像:Docker Hub 上不存在 conversejs 组织账号,检索 converse 得到的均为第三方无关镜像。因此实际选择只有两类:

方案说明取舍
第三方现成镜像直接 docker pull❌ 不采用:供应链不可控、版本滞后、构建过程不透明
自建镜像(本文)多阶段 Dockerfile:构建期用 npm 拉官方包取 dist,运行期 nginx 托管✅ 采用:全部构建材料只有 npm 官方包与两个官方基座镜像,20 行 Dockerfile 完全透明

自建镜像的设计要点:

  1. 构建与运行分离(多阶段构建):npm 只是取产物的工具,最终镜像里没有 Node.js,运行体积极小(121MB 中大部分是 nginx:alpine 基座与 dist 静态文件);
  2. 版本锁定:构建参数 CONVERSE_VERSION 锁定 14.0.1,升级时改参数重建;
  3. 配置与镜像分离:运行参数不放镜像里,由 config.js 经 bind mount 注入(见八、配置文件挂载),改配置不需要重建镜像。

三、前置条件

  1. 已安装 Docker 与 Docker Compose(本文实测版本 29.9.2 / v5.6.1);
  2. 构建阶段服务器需能访问 npm registry(拉取 converse.js 包)与 Docker Hub(拉取两个基座镜像);离线环境可在联网机器构建后 docker save 转运;
  3. 一个可连接的 XMPP 服务器 WebSocket/BOSH 端点:本文示例用 conversejs.org 官方公共端点 wss://conversejs.org/xmpp-websocket,生产对接自建服务端(搭建见《Ubuntu 22.04 安装 Prosody IM 13.0.7 指南》);
  4. 生产环境须在容器前再套一层 HTTPS 反向代理:SCRAM 密码认证依赖浏览器 WebCrypto,非 HTTPS(非 localhost)页面登录会直接失败(实测报错实录见本专栏《Converse.js 嵌入集成使用指南》篇)。

四、部署步骤

4.1 项目目录结构

mkdir -p /opt/conversejs
cd /opt/conversejs

最终目录内五个文件,下文逐个给出:

/opt/conversejs/
├── Dockerfile            # 多阶段构建
├── nginx.conf            # 容器内站点配置
├── index.html            # 聊天页(ESM 加载 + 初始化入口)
├── config.js             # 运行期配置(挂载注入,可在线修改)
└── docker-compose.yml    # 编排

4.2 Dockerfile

FROM node:22-slim AS build
ARG CONVERSE_VERSION=14.0.1
WORKDIR /build
RUN npm install converse.js@${CONVERSE_VERSION} --no-audit --no-fund

FROM nginx:alpine
COPY --from=build /build/node_modules/converse.js/dist /usr/share/nginx/html/dist
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY index.html /usr/share/nginx/html/index.html
COPY config.js /usr/share/nginx/html/config.js

逐段说明:第一阶段在 node:22-slim 里用 npm 安装指定版本(${CONVERSE_VERSION} 引用构建参数),产物落在 /build/node_modules/converse.js/dist;第二阶段把 dist 拷进 nginx:alpine 的站点目录 /usr/share/nginx/html/dist(必须保持 /dist/ 子路径,原因见本专栏《Ubuntu 22.04 安装 Converse.js 14 指南》9.2 节的 emoji 404 踩坑),再拷入站点配置与页面。构建参数默认值 14.0.1,构建时可用 --build-arg CONVERSE_VERSION=<版本> 覆盖。

4.3 nginx.conf

server {
    listen 80;
    server_name _;
    root /usr/share/nginx/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~* \.(js|css|woff2?|mp3|ogg|png|svg|ico|json|wasm)$ {
        expires 7d;
        add_header Cache-Control "public";
    }
}

说明:纯静态站点,try_files 兜底 404;静态资源统一缓存 7 天(dist 内容随镜像版本更新,可安全长缓存)。实测 nginx:alpine(1.31.8)已内置 wasm MIME 类型,curve25519_compiled.wasm 响应头为 Content-Type: application/wasm,无 Ubuntu apt 源 nginx 1.18 的 wasm MIME 缺失问题。

4.4 index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Converse.js 全屏聊天</title>
  <link rel="stylesheet" href="/dist/converse.min.css">
  <script type="module" src="/dist/converse.min.js"></script>
  <script src="/config.js"></script>
</head>
<body>
  <script type="module">
    converse.initialize(window.CONVERSE_CONFIG || {});
  </script>
</body>
</html>

两个关键点:其一,v14 产物是 ES Module,/dist/converse.min.js 与内联初始化脚本都必须用 <script type="module">(加载失败的现象与排障见本专栏《Ubuntu 22.04 安装 Converse.js 14 指南》9.1 节);其二,初始化参数来自 /config.js 注入的 window.CONVERSE_CONFIG,镜像本身不含任何环境特定配置。

4.5 config.js

// Converse.js 运行期配置(挂载注入,不随镜像构建固化)
// 配置项全集见[《Converse.js 14 配置参数详解》](https://www.quzuo.net/document/r8JTSBUOmOQg)
window.CONVERSE_CONFIG = {
  // 你的 XMPP 服务器 WebSocket 端点(也可用 bosh_service_url 走 BOSH)
  websocket_url: "wss://conversejs.org/xmpp-websocket",
  // 全屏模式;嵌入已有页面用 overlayed
  view_mode: "fullscreen",
  authentication: "login",
  allow_registration: true,
  discover_connection_methods: true,
  i18n: "zh_CN",
  play_sounds: true,
  show_controlbox_by_default: true
};

⚠️ 注意:对接自建 XMPP 服务器、且 JID 域名不可被浏览器解析(内网域名、localhost)时,必须把 discover_connection_methods 改为 false,否则 XEP-0156 端点发现请求失败会阻断登录(实测实录见本专栏《Converse.js 嵌入集成使用指南》篇)。

4.6 docker-compose.yml

name: conversejs-14.0.1-stack

services:
  conversejs:
    build:
      context: .
      args:
        CONVERSE_VERSION: 14.0.1
    image: conversejs:14.0.1
    container_name: conversejs-14.0.1-web
    restart: unless-stopped
    ports:
      - "8132:80"
    volumes:
      - ./config.js:/usr/share/nginx/html/config.js:ro
    networks:
      - conversejs-net

networks:
  conversejs-net:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.72.0/24

逐项说明:build.args.CONVERSE_VERSION 传入 Dockerfile 的构建参数;image 给构建产物命名打标签,便于复用;container_name 固定容器名便于运维定位;ports 把宿主 8132 映射到容器 80(端口冲突时改左侧宿主端口即可);volumes 以只读方式把宿主 config.js 挂载进容器覆盖镜像内同名文件——这是「改配置免重建」的关键;networks 建独立桥接网络并指定子网,避免与宿主机其他项目网段冲突(不需要指定子网时可删除整个 ipam 段)。

4.7 构建与启动

cd /opt/conversejs
docker compose build
docker compose up -d

构建过程为「拉基座镜像 → npm install → 拷贝产物」,完成后核对镜像:

docker images conversejs

实测回显:

conversejs:14.0.1 121MB

docker compose up -d 实测回显:

 Network conversejs-1401-stack_conversejs-net Creating 
 Network conversejs-1401-stack_conversejs-net Created 
 Container conversejs-14.0.1-web Creating 
 Container conversejs-14.0.1-web Created 
 Container conversejs-14.0.1-web Starting 
 Container conversejs-14.0.1-web Started 

💡 说明:Compose 会把项目名里的点号消毒后再作资源前缀,所以实际网络名是 conversejs-1401-stack_conversejs-net,属正常现象。

4.8 验证

容器状态:

docker compose ps

实测回显:

NAME                    IMAGE               COMMAND                  SERVICE      CREATED          STATUS          PORTS
conversejs-14.0.1-web   conversejs:14.0.1   "/docker-entrypoint.…"   conversejs   22 minutes ago   Up 18 minutes   0.0.0.0:8132->80/tcp, [::]:8132->80/tcp

首页与核心静态资源:

curl -sI http://127.0.0.1:8132/

实测回显:

HTTP/1.1 200 OK
Server: nginx/1.31.8
Content-Type: text/html
Content-Length: 459
curl -sI http://127.0.0.1:8132/dist/converse.min.js

实测回显:

HTTP/1.1 200 OK
Server: nginx/1.31.8
Content-Type: application/javascript
Content-Length: 1308228

挂载的配置文件确认注入生效:

curl -s http://127.0.0.1:8132/config.js | head -4

实测回显:

// Converse.js 运行期配置(挂载注入,不随镜像构建固化)
// 配置项全集见[《Converse.js 14 配置参数详解》](https://www.quzuo.net/document/r8JTSBUOmOQg)
window.CONVERSE_CONFIG = {
  // 你的 XMPP 服务器 WebSocket 端点(也可用 bosh_service_url 走 BOSH)

浏览器侧验证(Chromium 无头模式加载 http://127.0.0.1:8132/):登录表单正常渲染,config.js 注入的初始化参数(中文界面、全屏模式)生效。浏览器访问 http://<宿主机IP>:8132/ 即可看到中文登录界面。

五、数据持久化说明

Converse.js 是纯前端应用,容器内没有任何需要持久化的服务端状态:

  • 会话与缓存数据在浏览器侧(IndexedDB/localStorage,由 persistent_store、keepalive 等参数控制),容器删了用户端数据也不丢;
  • 消息与账号数据在 XMPP 服务端(Prosody/ejabberd 等),不在本栈;
  • 容器侧唯一需要保留的「数据」是 /opt/conversejs/ 目录下的五个文件本身(其中 config.js 经 bind mount 常驻宿主)。

因此本栈不配置任何 named volume,升级换版直接重建容器即可,无数据迁移负担。

六、环境变量表

本栈刻意不使用运行时环境变量——Converse.js 的全部运行参数由 config.js 挂载注入(见八),避免「env 与配置文件两套来源」的混乱。唯一的变量是构建期参数:

变量类别默认值说明
CONVERSE_VERSION构建参数(build arg)14.0.1要安装的 npm 包版本;升级时改这里或 docker compose build --build-arg CONVERSE_VERSION=<版本>

七、配置参数说明

config.js 中各初始化参数的含义:

参数本文值说明
websocket_urlwss://conversejs.org/xmpp-websocketXMPP WebSocket 端点;生产换成自建服务端,如 wss://xmpp.example.com/xmpp-websocket
bosh_service_url未用与 websocket_url 二选一,走 BOSH 长轮询传输
view_modefullscreen整页模式;嵌入既有页面用 overlayed(右下浮窗)或 embedded(页面内区域)
authenticationlogin登录方式(login/external/anonymous/prebind)
allow_registrationtrue显示注册表单(需服务端开启 XEP-0077 带内注册)
discover_connection_methodstrueXEP-0156 端点自动发现;JID 域名不可解析时必须改 false(见 4.5 ⚠️)
i18nzh_CN界面语言(简体中文)
play_soundstrue收到私聊/被@时播放提示音(音频文件在 dist/sounds/)
show_controlbox_by_defaulttrue打开页面即显示登录/联系人控制框

以上仅为常用项,全部 153 个配置项的默认值、取值范围与逐项详解见本专栏《Converse.js 14 配置参数详解》篇。

八、配置文件挂载

运行期配置唯一的注入点是这条 bind mount(docker-compose.yml 中已配置):

    volumes:
      - ./config.js:/usr/share/nginx/html/config.js:ro
  • :ro 只读挂载,容器内无法篡改配置;
  • 修改配置 = 编辑宿主 /opt/conversejs/config.js,不需要重建镜像、也不需要重启容器(nginx 直接读挂载文件);

⚠️ 注意(实测):config.js 是 .js 后缀,会命中 nginx.conf 的 7 天静态缓存规则,实测响应头带 Cache-Control: max-age=604800。改完配置后浏览器必须硬刷新(Ctrl+F5)或开隐私窗口验证,否则看到的仍是缓存里的旧配置;如需频繁改配置,可在 nginx.conf 中为 config.js 单独加一条不缓存的 location。

nginx.conf、index.html 是构建期 COPY 进镜像的,修改后需 docker compose build 重建;若希望它们也可在线改,自行追加同形式的 bind mount 即可。

九、等价 docker run

不用 Compose 时的等价命令(构建参数与挂载与 4.6 一致):

cd /opt/conversejs
docker build -t conversejs:14.0.1 --build-arg CONVERSE_VERSION=14.0.1 .
docker network create --subnet 10.89.72.0/24 conversejs-net
docker run -d \
  --name conversejs-14.0.1-web \
  --restart unless-stopped \
  --network conversejs-net \
  -p 8132:80 \
  -v /opt/conversejs/config.js:/usr/share/nginx/html/config.js:ro \
  conversejs:14.0.1

升级版本(以升到新版为例):改 docker-compose.yml 里两处 14.0.1(或 docker build --build-arg CONVERSE_VERSION=<新版本>),重新 docker compose build && docker compose up -d,浏览器硬刷新即可。

十、常用运维命令

查看运行状态与资源占用:

docker compose ps
docker stats conversejs-14.0.1-web --no-stream

查看实时日志(nginx access/error):

docker compose logs -f conversejs

实测日志尾部回显(启动后 nginx worker 就绪):

conversejs-14.0.1-web  | 2026/10/25 04:52:46 [notice] 1#1: start worker process 30
conversejs-14.0.1-web  | 2026/10/25 04:52:46 [notice] 1#1: start worker process 31

重启与停止、启动:

docker compose restart
docker compose stop
docker compose start

整体销毁(保留镜像与项目目录,可随时 up -d 拉起):

docker compose down

实测回显:

 Container conversejs-14.0.1-web Stopping 
 Container conversejs-14.0.1-web Stopped 
 Container conversejs-14.0.1-web Removing 
 Container conversejs-14.0.1-web Removed 
 Network conversejs-1401-stack_conversejs-net Removing 
 Network conversejs-1401-stack_conversejs-net Removed 

彻底卸载(含镜像):

docker compose down
docker rmi conversejs:14.0.1
rm -rf /opt/conversejs

十一、常见问题(FAQ)

11.1 为什么不用 Docker Hub 上现成的 converse 镜像

Docker Hub 没有 conversejs 组织账号,检索到的同名镜像均为第三方发布,构建材料与更新频率不可控,把登录页面(处理用户口令的第一入口)交给不可信镜像有明确供应链风险。本文 Dockerfile 仅 20 行、构建材料只有 npm 官方包与两个官方基座镜像,透明可审计,自建是更稳妥的选择。

11.2 改了 config.js 但页面没变化

按八、配置文件挂载的 ⚠️ 处理:config.js 命中 7 天静态缓存(实测响应头 Cache-Control: max-age=604800),浏览器硬刷新(Ctrl+F5)或隐私窗口验证;排除浏览器缓存后仍不生效,再核对 docker compose ps 确认容器在运行、curl -s http://127.0.0.1:8132/config.js 确认服务端返回的已是新内容。

11.3 页面打开空白,控制台报 converse is not defined

v14 产物是 ES Module,必须用 <script type="module"> 加载。本文 4.4 的 index.html 已按此编写;若自行改过页面模板,核对两处 script 标签的 type="module" 是否都在。完整排障过程见本专栏《Ubuntu 22.04 安装 Converse.js 14 指南》9.1 节。

11.4 提交登录后控制台 Failed to fetch,无法登录

JID 域名不可解析(内网域名或 localhost)时,默认开启的 discover_connection_methods 会去请求 https://<域名>/.well-known/host-meta 并失败阻断登录。把 config.js 中 discover_connection_methods 改为 false,硬刷新后重试;该坑的完整实测实录见本专栏《Converse.js 嵌入集成使用指南》篇。

11.5 端口 8132 被占用

改 docker-compose.yml 中 ports 的左侧宿主端口(如 "8200:80"),docker compose up -d 生效,容器内服务端口恒为 80 无需改动。

十二、参考链接

本专栏其他篇目:《Converse.js 介绍与选型指南》、《Ubuntu 22.04 安装 Converse.js 14 指南》、《Converse.js 14 配置参数详解》、《Converse.js 嵌入集成使用指南》。