MistServer 3.12 Docker Compose 部署指南

基于 ddvtech/mistserver:3.12 官方发行版实测:compose 编排与 shm_size 硬前置、4242 首启向导建号、RTMP/RTSP 推流与 HLS/DASH/VoD 拉流全链路验证及排障。

MistServerMistServer流媒体2026/10/30

MistServer 3.12 Docker Compose 部署指南

目标:在一台 Linux 服务器上用官方发行版 ddvtech/mistserver:3.12 完成多协议流媒体服务从零到一的部署:编排文件逐行说明、首次启动向导(建号 + 协议连接器)、RTMP/RTSP 推流与 HLS/DASH 拉流全链路验证,以及部署期最常见的共享内存与端口路由问题排障。本文所有命令与回显均在 2026-10-30 的实测中逐条执行验证。

本文是 MistServer 系列的第二篇。第一篇《MistServer 3.12 介绍与选型指南》讲清了"它是什么、协议矩阵有多宽、适不适合你",本篇解决"怎么把它跑起来"。流媒体源站的搭建与转推场景如果需要一套轻量参考,可以对照阅读 《MediaMTX 1.21.3 Docker Compose 部署指南》,两篇的验证方法(推流、拉流、冒烟三件套)保持了同一套范式,方便横向比较。

一、环境信息

项目值
组件版本MistServer 3.12(2026-10-05 发布,官方 GitHub Releases,2026-10-30 实查)
发行形态官方 Docker 发行版 ddvtech/mistserver:3.12(Docker Hub,2026-10-30 实查)
服务器系统Linux x86_64(内核 6.x)
管理界面4242 端口(Web UI 与 Management API 同口)
协议端口1935 RTMP、5554 RTSP、8080 HTTP(HLS/DASH/WebRTC 元数据)、8889/udp 与 18203/udp
实测日期2026-10-30

3.12 的管理口在首次启动时只有一个 4242 在监听——RTMP、HTTP 等协议监听口都要在管理界面(或 API)里显式启用后才会拉起,这是 3.x 的明确设计。所以本篇的部署步骤里"首启向导"不是可跳过的形式,而是协议服务真正对外服务的开关。

二、部署形态与资源预算

2.1 官方发行版的两种形态

官方在下载页与 Docker Hub 提供两类镜像形态(mistserver.org/download,2026-10-29 查询):

  • 含操作系统的完整形态:内置 Ubuntu 基座,可以用脚本、可以进服务排障,官方 Docker 文档的示例命令默认指向这类;
  • 纯二进制精简形态:只打包 MistServer 全套可执行文件,体积更小,但里面没有 shell 工具链,无法在运行环境内补装分析工具。

两种形态的入口一致:进程以 MistController 为核心,配置持久化在 /config.json 单文件。本篇采用完整形态 ddvtech/mistserver:3.12,实测排障时需要在运行环境里看进程列表、查日志,完整形态更合适。

2.2 共享内存:必须显式配置的硬前置

MistServer 的进程模型依赖 POSIX 共享内存交换数据:每条流的每个轨道默认申请 40MB 共享内存环形缓冲。而默认共享内存只有 64MB——这是本系列实测踩到的第一个故障,首启日志里 MistController 会直接警告:

[2026-10-30 04:30:18] WARN: You have very little shared memory available (63 MiB). Mist heavily relies on shared memory: please ensure your shared memory is set to a high value, preferably ~95% of your total available RAM.
[2026-10-30 04:30:18] WARN: Tip: If you are using docker, e.g. add the `--shm-size=15143m` parameter to your `docker run` command to fix this.

(日志节选自实测首启输出。)

共享内存预算公式(实测数据推导):

/dev/shm ≥ 并发流数 × 平均轨道数 × 40MB + 元数据余量

10 路音视频双轨直播流 = 10 × 2 × 40MB = 800MB。实验与中小规模生产建议直接 shm_size: "1gb";更大规模按公式放大。官方文档也强调默认 64MB "barely enough to do anything"(mistserver.org 文档 Docker 章节,2026-10-29 查询)。

2.3 端口规划

本篇实测端口矩阵(宿主侧统一用 81xx 高位段,规避与既有服务冲突):

宿主端口服务端口协议用途
81324242/tcpWeb 管理界面 + Management API
81338080/tcpHTTP 输出:HLS(/hls/)、CMAF/DASH(/cmaf/)、WebRTC 播放页与元数据
81351935/tcpRTMP 收流/推流
81395554/tcpRTSP 收流/推流
81408889/udpSRT(TSSRT 连接器,默认 UDP 8889)
814118203/udpWebRTC(SRTP UDP socket,默认 UDP 18203)

规划原则:4242 是管理面,不要暴露公网;8080 是 HTTP 家族的总入口(3.x 用路径前缀区分 HLS/DASH/WebRTC,见 4.4 节实测);UDP 端口(8889、18203)发布时必须带 /udp 后缀,漏写后缀会被按 TCP 解析导致对应协议拉流失败——这是编排文件最容易抄错的一行。两个 UDP 口的默认值来自连接器能力清单(capabilities)的实测读回:TSSRT 连接器默认 port: 8889、WebRTC 连接器默认 port: 18203。

三、前置条件

  1. 服务器已安装 Docker 与 Docker Compose v2(docker compose version 可执行);
  2. 宿主 8132/8133/8135/8139/8140/8141 六个端口空闲:ss -ltnp | grep -E '8132|8133|8135|8139' 确认无占用(UDP 口用 ss -lunp 查);
  3. 准备持久化目录:管理配置单文件与 VoD 媒体目录,本篇统一放工作数据目录(示例为 /opt/mistserver,读者可按自己的目录规范替换):
mkdir -p /opt/mistserver/data /opt/mistserver/vod
touch /opt/mistserver/data/config.json
  1. (可选)准备一个测试用 MP4 文件放入 vod/,本篇用 testvod.mp4(640×360、25fps、含 AAC 音轨,时长约 10 秒)演示 VoD 点播流。

四、部署步骤

4.1 编写 docker-compose.yml

在 /opt/mistserver/ 下编写编排文件。项目名显式声明为 mistserver-3.12-stack——多套流媒体服务并行部署时,统一规范的项目名能避免操作互相误伤:

name: mistserver-3.12-stack

services:
  mistserver:
    image: ddvtech/mistserver:3.12
    container_name: mistserver-3.12-app
    restart: unless-stopped
    shm_size: "1gb"
    ports:
      - "8132:4242"      # Web 管理界面 / Management API
      - "8133:8080"      # HTTP:HLS / CMAF(DASH) / WebRTC 播放页
      - "8135:1935"      # RTMP 收流/推流
      - "8139:5554"      # RTSP 收流/推流
      - "8140:8889/udp"  # SRT(TSSRT 连接器默认 UDP 8889)
      - "8141:18203/udp" # WebRTC(SRTP UDP socket 默认 18203)
    volumes:
      - /opt/mistserver/data/config.json:/config.json
      - /opt/mistserver/vod:/vod
    networks:
      - mistserver-net

networks:
  mistserver-net:
    name: mistserver-3.12-net
    driver: bridge

逐行说明:

  • name: mistserver-3.12-stack:Compose 项目名,所有资源(网络、服务)以它为前缀,docker compose down 只影响本项目;
  • shm_size: "1gb":共享内存上限,2.2 节的硬前置。漏掉它,流会拉不起来且日志只有一句模糊提示;
  • ports 六行:TCP 四个 + UDP 两个。8140、8141 两行若漏写 /udp,启动时映射类型错误;
  • volumes 两行:/config.json 是 MistServer 唯一的持久化状态(账号、协议连接器、流配置全在里面,实测确认它由服务进程自动写回);/vod 挂载点播素材,容器内路径与流配置的 source 一一对应(4.4 节 VoD 流的 source 就是 /vod/testvod.mp4);
  • networks:显式命名网络,避免 Compose 用项目名哈希生成随机网络名。

💡 技术拓展:同样是"官方 Docker 发行版",流媒体服务器的端口暴露策略与普通 Web 服务不同。普通服务暴露一个 HTTP 口即可;流媒体服务器是"多协议多端口"形态——RTMP(1935)、RTSP(5554)、HTTP 家族(8080)、WebRTC(8889/udp)各自独立监听。另一种极端做法是宿主网络模式(官方文档对 Linux 推荐 --network=host):省去端口映射、UDP 类协议(WebRTC/SRT)配置更简单,代价是没有端口隔离层、端口冲突要自己兜底。本篇选端口映射模式:端口收敛可控,且便于和反向代理配合;如果后续要上 WebRTC 大规模并发或 SRT 广电流,再评估切宿主网络模式。

4.2 启动与首启确认

cd /opt/mistserver
docker compose up -d
docker compose ps

实测回显:

NAME                  IMAGE                     COMMAND                  SERVICE      STATUS
mistserver-3.12-app   ddvtech/mistserver:3.12   "/usr/local/bin/Mist…"   mistserver   Up 4 seconds

启动后先看首启日志,确认服务自身状态与共享内存告警是否出现:

docker compose logs mistserver | head -20

实测回显(节选):

mistserver-3.12-app  | [2026-10-30 04:30:18] CONF: No login configured. No protocols enabled. No streams configured. This can be configured through the web interface on port 0 or through the API
mistserver-3.12-app  | [2026-10-30 04:30:18] CONF: Controller started

Controller started 即管理面就绪。此时用 ss -ltn 看宿主端口,会确认 2.1 节的判断:只有 8132(映射的 4242)在监听,其余协议口要等 4.3 节首启向导里启用连接器后才出现。

4.3 首启向导:建号与启用协议连接器

首启有两种完成方式:浏览器打开 http://<服务器IP>:8132 走 Web 向导,或直接调 Management API。两种方式写入的是同一份 /config.json,效果等价。演示环境是命令行友好场景,这里把两条路都走一遍。

方式一:Web 界面(推荐)

浏览器打开 http://<服务器IP>:8132,首启流程三步:

  1. 创建管理员账号:界面提示 "There is currently no username or password set"(当前未设置任何账号),填写用户名与密码后提交。本系列演示统一使用账号 root、密码 q1w2e3r4(演示账号,生产环境务必换强密码);
  2. 确认协议连接器:向导给出默认协议集(RTMP、RTSP、HTTP、HLS、CMAF 等),首次部署建议直接采用默认值——实测默认集已覆盖本篇全部验证场景;
  3. 进入主界面:左侧导航包含 Streams(流管理)、Protocols(协议连接器)、Accounts(账号)、Limits、Triggers、Logs 等配置域,具体逐项说明见本系列配置篇。

方式二:API 建号

无账号状态(NOACC)下允许通过 API 创建初始账号。先请求任意接口拿到认证挑战,再用挑战值完成创建。实测全程(curl 与回显):

# 1. 无账号探测:返回 NOACC
curl -s 'http://127.0.0.1:8132/api2?command=%7B%7D'
{"authorize":{"status":"NOACC"}}
# 2. 创建初始账号(明文,仅限首次建号且仅限内网使用)
curl -s 'http://127.0.0.1:8132/api2' -H 'Content-Type: application/json' \
  -d '{"authorize":{"new_username":"root","new_password":"q1w2e3r4"}}'
{"authorize":{"status":"ACC_MADE"}}

ACC_MADE 表示账号已建立。官方文档明确提醒这种方式"不安全",只该出现在首次部署的内网环节。

建号后服务端日志有对应记录(实测):

CONF: Created account root through API

4.4 创建流:三种典型 source

流是 MistServer 的核心配置对象。管理界面 Streams → Add stream 或 API 均可创建。三种典型 source 本篇全部实测:

source 写法类型行为
push://实时推流等待编码器向 RTMP/RTSP 端口推流,流名匹配即接入
/vod/testvod.mp4文件点播立即就绪,循环/按需供拉流
push://streamname限定流名推流只接受推到指定流名的推流会话

API 方式创建(addstream 命令,请求体必须是 JSON——实测中发现 form 表单方式提交写操作不生效,详见 D 篇排障):

curl -s 'http://127.0.0.1:8132/api' -H 'Content-Type: application/json' \
  -d '{"addstream":{"live":{"name":"live","source":"push://"}}}'
{"authorize":{"status":"OK"},...}

Web 界面操作等价:Streams 页 → Add stream → 流名 live、source 选 Stream(即 push://)→ Save。创建后流列表出现 live,状态为离线(等待推流)。

再创建一条 VoD 流验证点播链路(source 填 /vod/testvod.mp4,即 4.1 节挂载目录内的文件)。创建成功后流列表里 vod 显示可用状态——实测其状态值为 online: 2,表示"文件流就绪":

{"vod": {"error": "Available", "name": "vod", "online": 2, "source": "/vod/testvod.mp4"}}

4.5 协议连接器确认

Protocols 页(或 API 的 config.protocols)应显示默认五项全部在线。实测读回:

[{"connector": "RTMP", "online": 1, "port": "1935"},
 {"connector": "RTSP", "online": 1, "port": "5554"},
 {"connector": "HTTP", "online": 1, "port": "8080"},
 {"connector": "HLS",  "online": 1},
 {"connector": "CMAF", "online": 1}]

online: 1 表示连接器已拉起。HLS 与 CMAF 没有独立端口——它们寄生于 HTTP 连接器的 8080 端口,靠 URL 前缀路由(下一节实测)。此时宿主侧再看端口,8133/8135/8139 已全部进入监听。

4.6 推拉流全链路验证

RTMP 推流到 live(用 ffmpeg 从测试源推流,生产环境此角色是编码器或导播台):

ffmpeg -re -f lavfi -i testsrc=size=640x360:rate=25 \
       -f lavfi -i sine=frequency=1000 \
       -c:v libx264 -preset veryfast -pix_fmt yuv420p -g 50 \
       -c:a aac -f flv rtmp://<服务器IP>:8135/live/live

推流地址是两段式:/live/live 前一段是应用名、后一段是流名,两段缺一不可——只推一段会被服务端日志拒绝(实测回显:Push rejected - stream not configured or unavailable,空流名)。

推流成功后,管理界面 Streams 页 live 状态变绿,API 读回(实测):

{"live": {"name": "live", "online": 1, "source": "push://"}}

RTSP 推流到 cam(模拟摄像头接入,source 同样是 push://):

ffmpeg -re -f lavfi -i testsrc2=size=640x360:rate=25 \
       -f lavfi -i sine=frequency=500 \
       -c:v libx264 -preset veryfast -pix_fmt yuv420p -g 50 \
       -c:a aac -f rtsp rtsp://<服务器IP>:8139/cam

HLS 拉流验证(HTTP 8080 家族,宿主映射 8133):

curl -s 'http://127.0.0.1:8133/hls/live/index.m3u8'

实测回显:

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=131392,RESOLUTION=640x360,FRAME-RATE=25,CODECS="avc1.64001e,mp4a.40.2"
1_2/index.m3u8?tkn=207935232

子播放列表与分片同样可拉(实测):

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:3
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-PROGRAM-DATE-TIME:2026-10-30T04:06:35.794Z
#EXTINF:2.000000,
2000_4000.ts?tkn=2981602234

分片请求实测 http=200 bytes=57716,HLS 链路完整。浏览器播放地址即 http://<服务器IP>:8133/hls/live/index.m3u8(Chrome 原生播 HLS 仍不稳,前端建议配 hls.js)。

DASH 拉流验证(CMAF 连接器,前缀 /cmaf/):

curl -s 'http://127.0.0.1:8133/cmaf/vod/index.mpd' | head -8

实测回显(VoD 流,静态 MPD):

<?xml version="1.0" encoding="UTF-8"?>
<MPD type="static" mediaPresentationDuration="PT9.960S" minBufferTime="PT1.5S" ... >
<ProgramInformation><Title>vod</Title></ProgramInformation>
<Period >
<AdaptationSet group="1" mimeType="video/mp4" width="640" height="360" frameRate="25" ... >

RTSP 拉流验证(从 cam 拉流解码 1 秒,实测回显末帧):

frame=   26 fps= 12 q=-0.0 Lsize=N/A time=00:00:01.03 bitrate=N/A speed=0.493x

VoD 直链验证:http://<服务器IP>:8133/hls/vod/index.m3u8 返回主播放列表(实测回显含 BANDWIDTH=131680,RESOLUTION=640x360 变体行),证明挂载目录 + 文件 source 的点播链路可用。

流元数据 JSON:HTTP 口对每条活跃流提供元数据接口,3.12 实测可用路径是 http://<服务器IP>:8133/<流名>.json(实测回显含编码参数、分辨率、帧率):

[{"data":{"audiocodecid":10,"audiodatarate":67.38281249999999,"audiosamplerate":44100,...,"framerate":25,"height":360,...,"width":640},"time":0,"track":0}]

注意:文档旧版本里写的 json_<流名>.json 路径在 3.12 实测不可用(服务端把 json_live 整体当流名查找,日志报 Could not get stream 'json_live' config!),这个行为变化在配置篇与 API 篇都有展开。

五、数据持久化说明

数据位置说明
管理配置(账号/连接器/流)宿主 /opt/mistserver/data/config.json → 服务内 /config.json单文件全量状态,服务进程变更后自动写回(实测:API 建号、建流、改连接器后文件即时更新)
VoD 媒体宿主 /opt/mistserver/vod/ → 服务内 /vod/点播素材;文件流首次被拉起时会在同目录生成 <文件名>.dtsh 索引(实测确认)
共享内存服务内 /dev/shm非持久化,重启即释放;预算见 2.2 节

config.json 一旦建立了管理员账号,文件里就是密码的 MD5 摘要(实测格式 {"account":{"root":{"password":"<md5>"}}}),备份该文件等于备份整套管理面——请把宿主侧该目录纳入常规备份计划,并控制读取权限。

六、首启后的最小安全收敛

  1. 管理口收敛:4242 不应对公网。只在内网/堡垒机后暴露 8132,其余协议口按需开放;
  2. 强密码:演示账号 root / q1w2e3r4 仅限实验;生产部署在首启向导里直接设置强密码;
  3. API 免认证边界:本机(localhost)访问管理口不需要认证(官方文档明示),服务器上本机的其他进程都能直接控制管理面——共享宿主的场景要意识到这条边界;
  4. 带宽例外网段:配置里默认把内网网段(10/8、172.16/12、192.168/16、127/8)列入带宽统计例外,首启日志有 Adding default bandwidth exception ranges (local networks) 记录,公网暴露时按需复核。

七、常用运维命令

# 状态与日志
docker compose ps
docker compose logs -f mistserver

# 重启单个服务(配置改动后一般不需要,MistServer 配置即改即生效)
docker compose restart mistserver

# 停止与彻底清理(含网络)
docker compose down

升级版本:替换 compose 文件中的发行版标签(如 3.12 → 后续稳定版)后 docker compose up -d,/config.json 持久化的配置与流会原样保留——升级前请先备份该文件并核对新版本的 Release Notes 是否有协议路由变化(3.x 系列的路径前缀规则见 4.6 节)。

八、常见问题(实测排障)

Q1:流创建了但一直离线,日志只有"无法启动缓冲"类提示。 共享内存不足。首启日志的 WARN(63 MiB 警告)就是它。按 2.2 节公式给足 shm_size,1 音 1 视的流至少 80MB 余量起步。

Q2:推流被拒,日志 Push rejected - stream not configured or unavailable。 两种原因(实测都遇到过):一是流名未创建——MistServer 不会为未知流名自动建流;二是推流地址少了应用名段,rtmp://host:8135/live 只有一段,正确是 rtmp://host:8135/live/live。

Q3:/live/index.m3u8 返回 "Unsupported Media type / library failed to launch the required connector"。 3.x 的 HTTP 家族靠路径前缀路由:HLS 是 /hls/<流名>/index.m3u8、DASH 是 /cmaf/<流名>/index.mpd、WebRTC 播放页在 /webrtc/<流名>.html。裸流名路径是 2.x 的习惯,3.x 已不适用。

Q4:UDP 端口启动报错或 WebRTC 拉不通。 检查 ports 里 UDP 映射是否带了 /udp 后缀(2.3 节);宿主侧用 ss -lunp 确认 UDP 口在监听。

Q5:VoD 流报 "Stream open failed"。 依次核对:服务内路径与挂载点是否对应(compose 挂载 /vod,流 source 也要写 /vod/...);文件编码是否被支持(MP4/MKV/TS 等主流封装均在列,可用管理界面 Files 域确认);<文件名>.dtsh 索引是否生成(首次拉流时自动创建,目录只读会失败)。

九、参考链接