Chitchatter Docker Compose 部署指南

Chitchatter(main 分支 b0114d5)Docker Compose 从零部署:两阶段镜像构建、compose 逐项讲解、启动验证、构建参数表、配置挂载与升级回滚,全部命令实测。

ChitchatterChitchatterDockerDocker Compose自托管2026/10/25

Chitchatter Docker Compose 部署指南

目标:用 Docker Compose 从零构建并部署 Chitchatter(main 分支 commit b0114d5)——两阶段 Dockerfile(Node 构建 + Nginx 托管)、compose 文件逐项讲解、启动验证、构建参数与环境变量、升级与常见问题。已在 Ubuntu 22.04(Docker Engine + Compose v2)实测通过。

一、环境信息

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

  • 操作系统:Ubuntu 22.04(x86_64),Docker + Docker Compose v2
  • Chitchatter:main 分支 commit b0114d52eb786d240ef3a9d2b3691b215e29dbf0(项目无正式版本号,以 commit 锁定基线)
  • 构建产物镜像:chitchatter:main-b0114d5(实测磁盘占用 116MB,内容 32.1MB)
  • 运行时基础镜像:node:24-bookworm-slim(构建阶段)、nginx:alpine(运行阶段,Nginx 1.31.8)
  • 服务端口:宿主 8142 → 容器 80(示例端口,可按需改)
  • 自定义网络:10.89.69.0/24

⚠️ 网络说明:构建阶段需从 GitHub 克隆源码、从 npm 官方仓库安装依赖。若构建机访问 GitHub/npm 慢或失败,可为 Docker 守护进程或构建环境配置代理后再执行 docker compose build,本文实测环境构建通道为直连。

二、镜像选型说明

Chitchatter 官方没有发布预构建镜像(Docker Hub 无官方仓库),官方部署目标是 Vercel 静态托管。因此自托管容器化只有一条路:从源码构建。Chitchatter 是纯前端单页应用,构建产物是静态文件,运行时只需一个静态文件服务器——因此采用「Node 构建 + Nginx 托管」两阶段镜像,最终镜像不含 Node 与源码,体积与攻击面都最小:

方案最终镜像内容体积取舍
两阶段构建(本文)仅 Nginx + 静态产物(约 32MB 内容)小推荐:运行时无 Node,安全且轻量
单阶段 Node 直跑 vite previewNode + 全部依赖(>1GB)大仅调试用途,不推荐生产
托管到对象存储/CDN无容器—最省事,但无法配置 SPA 回退与 API 反代的场景不适用

三、前置条件

  • Docker Engine 20.10+ 与 Docker Compose v2(docker compose version 可验证);
  • 宿主磁盘空闲 ≥ 2GB(构建中间层含完整 node_modules);
  • 8142 端口未被占用(或改用其他端口);
  • (可选)需要「增强连接」TURN 下发时,另备 RTC 配置 API——见《Chitchatter 配置参数详解》篇,本文部署最小可用形态不含 API。

四、部署步骤

4.1 准备项目目录与 Dockerfile

mkdir -p /opt/chitchatter-stack && cd /opt/chitchatter-stack

创建 Dockerfile(两阶段:构建 → 托管):

FROM node:24-bookworm-slim AS build
ARG GIT_REPO=https://github.com/jeremyckahn/chitchatter.git
ARG GIT_COMMIT=b0114d52eb786d240ef3a9d2b3691b215e29dbf0
ARG VITE_RTC_CONFIG_ENDPOINT=""
RUN apt-get update \
    && apt-get install -y --no-install-recommends git ca-certificates \
    && rm -rf /var/lib/apt/lists/*
WORKDIR /build
RUN git clone "$GIT_REPO" . && git checkout "$GIT_COMMIT"
RUN npm ci --no-audit --no-fund
RUN if [ -n "$VITE_RTC_CONFIG_ENDPOINT" ]; then \
      VITE_RTC_CONFIG_ENDPOINT="$VITE_RTC_CONFIG_ENDPOINT" npm run build; \
    else \
      npm run build; \
    fi

FROM nginx:alpine
COPY --from=build /build/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80

创建同目录 nginx.conf(SPA 回退 + SDK 跨域头,二者缺一不可):

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

    location / {
        try_files $uri $uri/ /index.html;
    }

    location = /sdk.js {
        add_header Access-Control-Allow-Origin *;
        add_header Cache-Control "no-cache";
    }

    gzip on;
    gzip_types text/css application/javascript application/json image/svg+xml;
}

4.2 编写 compose 文件

name: chitchatter-main-stack

services:
  app:
    build:
      context: .
      args:
        GIT_COMMIT: b0114d52eb786d240ef3a9d2b3691b215e29dbf0
    image: chitchatter:main-b0114d5
    container_name: chitchatter-main-app
    restart: unless-stopped
    ports:
      - "8142:80"
    networks:
      - chitchatter-net

networks:
  chitchatter-net:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.69.0/24

逐项说明:

配置项作用
name:显式项目名,避免多栈目录同名互删
build.args.GIT_COMMIT锁定源码基线(无正式版本号,用 commit 哈希当版本)
image:给构建产物命名打标签,便于复用与升级比对
container_name / restart固定容器名 + 异常自动拉起
ports宿主 8142 → 容器 80(Nginx)
networks + ipam自定义网段,与其他栈隔离

4.3 构建并启动

docker compose build
docker compose up -d

构建耗时取决于网络(克隆 + npm ci 约 1600 个包),构建成功末尾可见镜像导出回显;启动后确认状态:

docker compose ps

实测回显:

NAME                   IMAGE                      COMMAND                  SERVICE   CREATED          STATUS          PORTS
chitchatter-main-app   chitchatter:main-b0114d5   "/docker-entrypoint.…"   app       30 minutes ago   Up 30 minutes   0.0.0.0:8142->80/tcp, [::]:8142->80/tcp

4.4 验证

逐条验证(首页、SPA 回退、SDK、镜像分层):

curl -s http://localhost:8142/ | grep -o '<title>[^<]*</title>'
<title>Chitchatter</title>
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8142/public/demo-room
200

(直接访问房间路由返回 200 而非 404,证明 try_files SPA 回退生效。)

curl -sI http://localhost:8142/sdk.js
HTTP/1.1 200 OK
Server: nginx/1.31.8
Content-Type: application/javascript
Content-Length: 3135
Access-Control-Allow-Origin: *
Cache-Control: no-cache
docker images chitchatter:main-b0114d5
IMAGE                      ID             DISK USAGE   CONTENT SIZE   EXTRA
chitchatter:main-b0114d5   040188f9b550        116MB         32.1MB   U

浏览器打开 http://<宿主IP>:8142/ 即可创建/加入房间。嵌入第三方页面用 http://<宿主IP>:8142/sdk.js(用法与 root-url 必配项见《Chitchatter 嵌入集成使用指南》篇)。

五、数据持久化说明

Chitchatter 无后端、无数据库、消息瞬态不落盘,没有需要持久化的应用数据,compose 文件因此不含任何卷。用户的昵称/主题等界面设置保存在浏览器 localStorage,与服务器无关。唯一会变的「状态」是静态产物本身——升级即重新构建镜像(见十、常用运维命令)。

六、环境变量表

compose 形态的可配置项全部是构建参数(构建时固化进静态产物,改后必须 docker compose build 重建):

构建参数(build.args)默认值说明
GIT_REPO官方仓库地址源码来源,fork 后改自己的仓库
GIT_COMMITb0114d52eb786d240ef3a9d2b3691b215e29dbf0源码基线 commit
VITE_RTC_CONFIG_ENDPOINT空(不注入)非空时构建出带「增强连接」功能的产物,如 /api/get-config

前端完整变量清单(VITE_ROUTER_TYPE、VITE_HOMEPAGE、VITE_TRACKER_URL 等)的语义与取舍见《Chitchatter 配置参数详解》篇;要在本方案中追加,只需在 Dockerfile 的构建 RUN 前加对应 ARG 并在 npm run build 前注入。

七、配置参数说明

运行时容器内只有一个 Nginx 进程,行为由镜像内 nginx.conf 决定(4.1 已逐项给出)。两个关键点:

  1. SPA 回退:try_files $uri $uri/ /index.html 是 browser 路由模式的硬需求;若构建时改用 VITE_ROUTER_TYPE=hash,此行可省(hash 路由不依赖服务器回退)。
  2. SDK 跨域:sdk.js 要被第三方页面 <script src> 引用,Access-Control-Allow-Origin: * 与 Cache-Control: no-cache 保证可用性与及时更新。

八、配置文件挂载

不想重建镜像、只想改 Nginx 配置时,把宿主配置挂进容器覆盖:

    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro

改后 docker compose restart app 生效。注意这只覆盖托管层配置,前端构建参数(VITE_*)改不了——它们已固化在静态产物里。

九、等价 docker run

不使用 compose 时的等价命令(先按 4.1 构建镜像):

docker build --build-arg GIT_COMMIT=b0114d52eb786d240ef3a9d2b3691b215e29dbf0 -t chitchatter:main-b0114d5 .
docker network create --subnet 10.89.69.0/24 chitchatter-net
docker run -d --name chitchatter-main-app --restart unless-stopped \
  --network chitchatter-net -p 8142:80 chitchatter:main-b0114d5

十、常用运维命令

docker compose ps                    # 查看状态
docker compose logs -f app           # 跟踪 Nginx 访问/错误日志
docker compose restart app           # 重启
docker compose down                  # 停止并删除栈(镜像保留)

升级流程(换 commit 基线):修改 compose 中 GIT_COMMIT 与 image 标签 → docker compose build → docker compose up -d(自动替换容器)。回滚即把标签指回旧镜像再 up -d。

十一、常见问题

Q1:构建卡在 git clone 或 npm ci? 构建机访问 GitHub/npm 受限。为 Docker 守护进程配置代理后重试(守护进程级代理对 docker build 的网络命名空间生效),或在公司内网先构建好镜像再 docker save | docker load 分发。

Q2:刷新房间页 404? 镜像内的 nginx.conf 缺 try_files $uri $uri/ /index.html。按 4.1 补齐后重建镜像(或按第八章挂载覆盖后重启)。

Q3:嵌入第三方页面后聊天没反应? 大概率是 root-url 未指向本实例——sdk.js 默认根地址固化的是官方站点(构建脚本取 package.json 的 homepage)。嵌入方加 root-url 属性,或构建前改 homepage。完整排查见《Chitchatter 嵌入集成使用指南》篇 4.3 节。

Q4:容器里需要配 HTTPS 吗? 本方案容器内是明文 80。生产环境在容器前再放一层 TLS 终止(外层 Nginx/Caddy/云负载均衡)即可;WebRTC 音视频要求最终页面必须是 HTTPS。

Q5:能直接用这个容器提供 TURN 配置 API 吗? simple-api-server.js 不在最终镜像里(两阶段构建只保留 Nginx + 静态产物)。需要「增强连接」时,按《Chitchatter 配置参数详解》篇 5.2 单独运行 API 进程,并在 nginx.conf 增加 /api/ 反代 location。

十二、参考链接

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