尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Docker部署SRS流媒体服务器:从零搭建直播服务实战指南

Docker部署SRS流媒体服务器:从零搭建直播服务实战指南 做音视频或者直播系统这行的朋友应该都绕不开 SRS 这个名字。SRSSimple Realtime Server是目前开源社区里非常活跃的一套实时流媒体服务器底层支持 RTMP、HTTP-FLV、HLS、WebRTC、SRT 这些协议常见场景基本都能覆盖。以前我折腾流媒体服务第一反应是在一台 Linux 裸机上编译 nginx-rtmp 或者手动装 SRS后来发现那套流程维护成本实在太高。最近我在测试环境里把整套直播服务迁到了 Docker 里用容器跑 SRS整个过程比预想中顺利得多正好趁这次机会把部署思路、命令、配置和踩过的坑一起整理出来。这篇文章会从一个可落地的角度讲清楚为什么要用 Docker 部署 SRS、环境要准备到什么程度、如何用 docker run 和 docker compose 把服务跑起来以及怎样用 OBS 或 FFmpeg 推流、用浏览器或 VLC 拉流验证效果。无论你是第一次接触流媒体的新手还是想把手头裸机服务容器化的老手都可以照着这套思路操作。先说一个整体感受Docker 部署 SRS 真正解决的不是“装不上”的问题而是“换环境后还能不能复现”的问题。容器把配置、依赖、运行环境全部固化到一起等于把那一堆脏活累活封装好了你只需要关心端口映射、挂载目录和配置内容这三件事。1. 先想清楚为什么是 SRS又为什么要套一层 Docker1.1 SRS 在整个实时音视频链路中的位置流媒体系统的链路通常可以分成三段采集端、服务端、播放端。OBS、摄像头、FFmpeg 属于采集端负责把画面和声音编码成流推出去播放端是 VLC、浏览器播放器、小程序、App 这些而服务端要做的事情就复杂了包括协议接收、转封装、分发、录制、鉴权、转码等等。SRS 就是这个“服务端”中的核心角色。SRS 为什么流行因为它把很多复杂能力都内置了。比如一个直播流推上来你希望 PC 浏览器能看、手机 H5 能看、App 播放器能看这三者的协议需求往往不一样。浏览器里 WebRTC 延迟最低H5 里 HLS 兼容性最好传统播放器则喜欢 RTMP 或 HTTP-FLV。如果靠自研你得为每个协议写一套接入逻辑而 SRS 可以同时对外提供这些协议推流端推一路播放端按需选用不同协议去拉服务端自动完成转封装。在 Docker 出现之前部署 SRS 需要在服务器上处理编译依赖、动态库、系统版本差异一通操作下来很容易把人劝退。现在有了官方镜像事情就变成了“拉镜像、起容器、映射端口”不管底层是 Ubuntu 还是 CentOS容器内部看到的运行环境都是一致的。1.2 与裸机编译比Docker 的方式好在哪我一开始用 SRS 的时候是在一台 2C4G 的云服务器上手动编译的。SRS 本身支持./configure make这套标准流程编译时间看机器性能一般几分钟到十几分钟。真正麻烦的是后续维护升级版本要重新编译换服务器要重新踩一遍环境坑出了问题很难说清是不是系统库版本不一致导致的。Docker 的方式把这些问题压缩成了几个固定的操作点。官方的ossrs/srs镜像里已经包含了编译好的 SRS 可执行文件、默认配置、依赖的动态库你不需要关心它是怎么编译出来的也不需要担心系统里缺少某个.so文件。容器启动失败直接删掉重建一条命令搞定完全不用怕把系统环境搞坏。当然Docker 也不是没有代价。容器和宿主机之间多了一层网络映射性能上多少会有一点损耗但对于绝大多数直播场景来说这个损耗完全可以忽略。真正要注意的是端口映射和存储卷的规划这也是我每次部署前都会反复确认的部分。1.3 部署前必须明确的端口和目录规划初次部署最容易犯的错就是端口漏映射。SRS 本身涉及多个服务端口每个端口对应不同能力我整理了一个常用对照表端口协议用途1935TCPRTMP 推流和拉流端口最基础1985TCPHTTP API 端口用于查询流信息、触发接口8080TCPHTTP 服务端口提供播放页面和 HLS 文件访问8000UDPWebRTC 媒体端口开启 RTC 时需要8001UDPWebRTC 媒体端口SRS 5 多路并发时需要扩到这里如果你只是想快速验证 RTMP 推流只要映射 1935 和 8080 就够了如果需要通过 API 查流状态再映射 1985WebRTC 场景下必须把 8000/UDP 甚至 8001/UDP 一并映射出去。目录方面SRS 默认会把 HLS 切片、日志、录制文件写到容器内的/usr/local/srs/objs目录。如果你希望这些文件在容器删除后还能保留或者想直接在宿主机上查看录制结果就需要把这个目录挂载出来。配置文件的挂载也很关键后面会详细说。2. 环境准备把 Docker 安装到能用的状态2.1 Linux 上快速安装 Docker EngineDocker 部署 SRS 的第一步当然是先让 Docker 本身跑起来。在 Ubuntu 这类系统上最快的办法是使用 Docker 官方提供的安装脚本curl -fsSL https://get.docker.com | bash这个脚本会自动检测系统版本、配置软件源、安装 Docker Engine 和 compose 插件。装完之后启动服务sudo systemctl enable docker sudo systemctl start docker sudo docker version看到 Client 和 Server 两段信息都正常返回就说明 Docker 已经可用了。国内服务器如果下载镜像比较慢可以在/etc/docker/daemon.json里配置镜像加速器配置完记得重启 Docker 服务sudo systemctl restart docker如果你是 CentOS 或者龙芯这类特殊架构安装方式会略微不同。CentOS 可以直接用yum install docker-ce龙芯、ARM 等架构需要确认镜像是否支持对应指令集。SRS 官方镜像目前对主流 amd64 和 arm64 都有支持普通用户不用担心。2.2 Windows 上用 Docker Desktop 的坑虚拟化检测失败怎么办在 Windows 上部署的常见方式是安装 Docker Desktop。但很多朋友安装完第一次启动界面直接弹出一行英文virtualization support was not detected意思是“没有检测到虚拟化支持”。这个报错通常有三个原因一是 BIOS 里没开虚拟化需要进主板设置把 Intel VT-x 或 AMD-V 打开二是 Windows 功能里的“虚拟机平台”没开可以在“启用或关闭 Windows 功能”里勾选“虚拟机平台”和“适用于 Linux 的 Windows 子系统”三是 Hypervisor 启动类型被关了需要以管理员身份打开终端执行bcdedit /set hypervisorlaunchtype auto执行完重启电脑再启动 Docker Desktop 一般就能正常了。还有一类情况是 Docker Desktop 已经启动但命令行执行docker ps时提示连接失败类似failed to connect to the docker api。这通常是 Docker Desktop 引擎还在初始化等十几秒再试或者直接右键托盘图标选择 Restart。2.3 镜像加速与 Docker Compose 环境校验Docker 装好后我习惯先确认两个东西一个是 Docker Compose 是否可用另一个是镜像拉取是否顺畅。Docker Compose 在较新版本中已经集成到 Docker CLI 里执行下面的命令可以验证docker compose version如果提示没有这个命令就需要单独安装 compose 插件。在 Linux 上可以下载二进制文件放到/usr/local/lib/docker/cli-plugins/目录也可以直接用apt install docker-compose-v2这类包名安装。镜像加速器的配置比较常规在/etc/docker/daemon.json中加上registry-mirrors字段即可。需要注意加速器只对 Docker Hub 的镜像有效其他第三方镜像仓库不一定生效。配置完成后可以用docker info查看当前 Registry Mirrors 是否已经加载。3. 基于 Docker 部署 SRS 的完整步骤3.1 第一次启动一条 docker run 先看到效果第一次跑通是最重要的一步先不追求复杂配置用官方镜像的默认配置把服务拉起来。docker pull ossrs/srs:5SRS 目前 5.x 是主力版本功能比 4.x 全面官方镜像也维护得比较积极。这里我建议直接指定版本号不要图省事用latest因为流媒体服务的接口和行为在不同大版本之间可能存在差异锁版本能降低升级的意外风险。接下来启动容器docker run -it --rm \ -p 1935:1935 \ -p 1985:1985 \ -p 8080:8080 \ ossrs/srs:5这个命令的意思是前台运行退出后自动删除容器同时把主机的 1935、1985、8080 端口映射到容器。启动后日志会直接打印在终端看到类似 “SRS is running” 的字样说明服务已经起来了。这时可以先用浏览器访问http://服务器IP:8080/players/SRS 自带了一个简单的演示播放页面。虽然现在还没有推流但至少说明 HTTP 服务端口是通的。3.2 自定义配置文件通过挂载实现真正的定制化默认配置适合跑通流程但实际部署通常会改配置。SRS 的配置是文本文件放在容器内的/usr/local/srs/conf/srs.conf。我们可以把宿主机上的配置文件挂载进去覆盖默认配置。先在宿主机创建一个srs.conf内容如下listen 1935; max_connections 1000; daemon off; srs_log_tank console; http_api { enabled on; listen 1985; } http_server { enabled on; listen 8080; dir ./objs/nginx/html; } vhost __defaultVhost__ { hls { enabled on; } http_remux { enabled on; mount [vhost]/[app]/[stream].flv; } }这份配置做了三件事开启 HTTP API 方便后面查流状态开启 HTTP 服务用于播放 HLS 和 HTTP-FLV在默认 vhost 上启用 HLS 切片和 HTTP-FLV 转封装。daemon off和srs_log_tank console这两行对容器环境很关键它们让 SRS 在前台运行并把日志输出到终端这样 Docker 的日志机制才能收集到 SRS 的运行日志。启动命令改成docker run -d --name srs \ -p 1935:1935 \ -p 1985:1985 \ -p 8080:8080 \ -v $PWD/srs.conf:/usr/local/srs/conf/srs.conf \ -v $PWD/objs:/usr/local/srs/objs \ ossrs/srs:5 \ ./objs/srs -c conf/srs.conf-v $PWD/objs:/usr/local/srs/objs这个挂载不是必须的但强烈建议加上。因为 HLS 切片、日志、录制的 DVR 文件都会写到这个目录挂载出来之后你直接在宿主机上就能查看文件容器升级也不会弄丢历史数据。3.3 用 docker compose 固化一套可维护的部署docker run适合测试生产环境我更推荐用docker compose。把容器配置写进一个 YAML 文件所有参数一目了然后续改动也只要改文件再执行一条命令。创建一个docker-compose.ymlservices: srs: image: ossrs/srs:5 container_name: srs restart: unless-stopped ports: - 1935:1935 - 1985:1985 - 8080:8080 - 8000:8000/udp - 8001:8001/udp volumes: - ./srs.conf:/usr/local/srs/conf/srs.conf - ./objs:/usr/local/srs/objs command: [./objs/srs, -c, conf/srs.conf]然后在同目录下执行docker compose up -drestart: unless-stopped的意思是容器异常退出会自动重启但如果你手动 stop 过它就不会自动拉起。这个策略适合大多数常驻服务。用 compose 还有一个好处以后要更新镜像只需要执行docker compose pull再docker compose up -d整个升级过程非常干净。3.4 顺便开启 HLS / WebRTC / 流鉴权等常见能力当基础跑通之后很多人会想进一步启用更多能力。这里我把常见的几个方向列一下。HLS 的配置已经在上面的配置文件里了启用后系统会在objs/nginx/html下生成.m3u8和.ts切片文件播放端直接访问http://IP:8080/live/test.m3u8即可。HLS 的缺点是有一定延迟但它兼容性最好适合对延迟不敏感的场景比如监控、课程回放。WebRTC 则是低延迟场景的利器。SRS 配置 WebRTC 时需要额外配置rtc_server并且candidate必须填服务器的实际 IP。这里有个很容易踩的坑如果你在云服务器上部署candidate 填内网 IP那么公网浏览器拿到这个 IP 就无法回连填公网 IP内网设备又不一定通。具体填什么要根据实际网络拓扑来定。对于 Webrtc 的浏览器拉流通常还需要 HTTPS 环境否则浏览器会限制摄像头和 WebRTC 能力。流鉴权方面SRS 支持通过 HTTP 回调、token 校验等方式做推流和拉流控制。比较常规的做法是在推流 URL 里带上 token 参数SRS 通过http_hooks把请求转发到你的业务服务由业务服务决定允许还是拒绝。这部分逻辑可以放在镜像是外的业务应用里SRS 只负责转发和拦截。4. 推流拉流联调把第一条直播流跑起来4.1 用 OBS 推 RTMP 流服务跑起来之后第一件事就是推一条真实的流测试。如果你电脑上有 OBS操作步骤非常简单。打开 OBS进入“设置 - 直播”服务选择“自定义...”服务器填rtmp://192.168.1.10/live这里的192.168.1.10要换成你运行 SRS 的服务器 IP。串流密钥填一个自定义流名比如test。然后点击“开始推流”如果 SRS 日志里出现对应的推流信息就说明推流成功。推流成功后可以用 VLC 播放器验证拉流。打开 VLC选择“打开网络串流”输入rtmp://192.168.1.10/live/test能看到画面就说明整条链路已经通了。4.2 没有摄像头用 FFmpeg 产生测试流很多朋友在服务器上测试时既没有摄像头也没有屏幕这时候可以用 FFmpeg 生成一段假信号流。只要服务器装了 FFmpeg或者你有另一台能访问 SRS 的机器执行下面这条命令ffmpeg -re -f lavfi -i testsrcsize1280x720:rate25 \ -f lavfi -i sinefrequency1000:sample_rate44100 \ -c:v libx264 -preset veryfast -tune zerolatency \ -c:a aac -shortest -f flv rtmp://127.0.0.1/live/testlavfi是 FFmpeg 内置的虚拟输入源testsrc会生成一个彩色测试画面sine会生成一个持续的单音非常适合做连通性测试。-re参数控制推流速度让 FFmpeg 按真实时间读取数据否则它可能会瞬间把所有帧推完。如果你手头有现成的 MP4 文件也可以直接循环推流ffmpeg -re -stream_loop -1 -i test.mp4 \ -c copy -f flv rtmp://127.0.0.1/live/test-c copy不做转码性能开销极小适合用来长时间测试服务稳定性。4.3 不同协议的拉流地址与播放验证SRS 最大的卖点就是一份流对应多种拉流协议。同样推live/test这一路流你可以用不同地址去拉。RTMP 地址rtmp://192.168.1.10/live/testHTTP-FLV 地址http://192.168.1.10:8080/live/test.flvHLS 地址http://192.168.1.10:8080/live/test.m3u8如果你开启了 WebRTC还可以通过浏览器播放器尝试 WebRTC 拉流。SRS 自带的演示播放器一般在http://192.168.1.10:8080/players/页面里可以填流名和选择播放协议。第一次打开如果画面出不来优先检查是否用了 HTTPSWebRTC 在很多浏览器中要求安全上下文以及 candidate 是否配置正确。5. 部署中常见的坑和排查办法5.1 端口不通、防火墙拦截端口不通是最常见的问题。判断方法很简单在推流端或者客户端机器上执行telnet 192.168.1.10 1935如果连接被拒绝或者超时基本可以断定是网络层的问题。常见原因有两个宿主机防火墙没放行端口或者云服务器的安全组策略没加规则。Linux 上如果启用了 ufw执行sudo ufw allow 1935/tcp sudo ufw allow 1985/tcp sudo ufw allow 8080/tcp sudo ufw allow 8000/udp sudo ufw allow 8001/udp云服务器还需要去控制台的安全组里放行对应端口。这里有个容易忽略的点UDP 端口和 TCP 端口在安全组里是不同条目别只加了 TCP 忘了 UDP。5.2 容器启动失败或日志反复报错容器启动失败时第一步一定是看日志docker logs -f srsSRS 的日志一般写得比较清楚常见的错误无非几种端口被占用、配置文件语法错误、目录没有写入权限。端口占用时执行ss -lntup | grep 1935或netstat -lntup | grep 1935找到占用进程要么停掉它要么换端口。配置文件语法错误时日志会直接告诉你哪一行不对注意检查括号是否闭合、分号是否漏掉。目录权限问题通常出现在挂载了宿主机目录之后比如挂载的./objs目录属主不是当前用户这时执行chmod 755或者chown调整一下即可。还有一个很容易忽略的点如果你用了 Windows 的 Docker Desktop挂载目录的权限和路径转换机制跟 Linux 不一样。Windows 挂载本地目录时SRS 内部看到的权限可能和宿主机不一致遇到写入失败的情况先检查目录是否在 Docker Desktop 的文件共享设置里。5.3 画面就是出不来试试这套排查顺序我每次联调遇到“推流成功了但播放不出画面”的情况都会按照固定顺序排查。第一步确认流真的在服务端。SRS 的 HTTP API 可以查询当前活动流curl http://127.0.0.1:1985/api/v1/streams如果返回结果里有applive、nametest这样的信息说明流确实推到服务端了。如果这里为空问题出在推流端或端口映射而不是播放端。第二步确认播放端能访问对端口。浏览器能打开http://IP:8080/players/不代表 1935 或 UDP 端口就是通的需要分别验证对应协议使用的端口。第三步排查播放器兼容性。RTMP 在主流浏览器里已经不能直接播放HTTP-FLV 也需要支持 flv.js 的播放器才能播放HLS 则要求播放器支持 HLS 协议。不要拿一个只支持 MP4 的播放器去测试 HLS 地址。第四步看日志。在推流的过程中观察docker logs -f srs的输出看有没有出现 “close stream” 或者 “invalid stream” 之类的异常。日志是定位问题最直接的证据。5.4 常见报错速查表报错或现象可能原因解决思路Docker Desktop 提示 virtualisation support wasn’t detectedBIOS 虚拟化未开启或 Hypervisor 未启用开启 BIOS 虚拟化执行 bcdedit 开启 hypervisorlaunchtype执行 docker 命令提示连接不上 Docker APIDocker Desktop 未启动或引擎初始化中启动 Docker Desktop等待后重试浏览器访问 8080 超时安全组或防火墙未放行放行 8080 TCP 端口推流始终失败SRS 日志无反应端口 1935 未映射或防火墙拦截确认 docker ps 端口映射放行 1935curl 1985 API 数据为空流已断开或推流没成功检查推流端日志确认流名称HTTP-FLV 播放黑屏http_remux 未开启或端口未映射配置 http_remux检查 8080 端口HLS 一直加载不出HLS 未开启或切片目录未写入开启 hls检查 objs 目录权限WebRTC 协商失败candidate 配置不对或未使用 HTTPS修正 candidate启用 HTTPSdocker compose命令不存在Compose 插件未安装安装 docker compose 插件服务器重启后容器不见了没有设置 restart 策略compose 中使用 restart: unless-stopped6. 后续的运维与扩容思路6.1 日志、健康检查与容器重启策略SRS 跑在容器里之后运维的关键就变成了“看 Docker 日志”和“看端口健康状态”。我一般会做两件事一是用docker logs --tail 100 -f srs实时查看日志二是写一个简单的健康检查每分钟探测一次 1935 端口和 1985 API如果连续失败就自动重启容器。compose 文件里可以直接配置健康检查services: srs: image: ossrs/srs:5 ... healthcheck: test: [CMD, curl, -f, http://127.0.0.1:1985/api/v1/health] interval: 30s timeout: 5s retries: 3SRS 在 1985 端口提供了几个 API 路径具体路径以当前版本为准。健康检查的好处是Docker 编排系统可以感知容器内的服务状态而不是只依赖进程是否存活。日志方面因为我设置了srs_log_tank consoleSRS 的日志会输出到 stdoutDocker 会负责收集和轮转。如果日志量特别大可以配置 Docker 的log-driver和log-opts限制单个文件大小比如logging: driver: json-file options: max-size: 10m max-file: 36.2 从单节点到多节点的扩展方向单机 SRS 能承载的并发有限遇到瓶颈时就要考虑扩展。SRS 本身支持 Origin-Edge 架构一台源站负责接收上游推流多台边缘节点负责给播放端分发播放端从最近的边缘节点拉流能明显降低源站压力。Docker 环境下这种方式很好实现源站和边缘节点都用同一个镜像只是配置文件不同。边缘节点只需配置 upstream 指向源站流量就会自动回源。用一个示例配置来说明vhost __defaultVhost__ { mode remote; origin 192.168.1.10; }这就是 SRS 的 edge 模式流从源站拉取播放端连到 edge 节点时实时流会从 origin 拉回来。多节点部署时要特别注意网络带宽和时延UDP 的 WebRTC 流对网络抖动更敏感跨地域部署时优先用 TCP 协议或考虑专门的加速链路。最后再提一个我个人很推荐的做法把 srs.conf 和 docker-compose.yml 一起放在 Git 仓库里任何一次配置变更都有记录。这样即使容器数据全丢也能从仓库快速恢复整套服务。Docker 部署 SRS 说到底就是这么点事环境准备好、镜像拉下来、配置挂进去、端口放行一条直播链路就通了。接下来的视频转码、录制、多协议分发、鉴权拦截都是在这套底座上慢慢长出来的能力你完全可以按需加。
返回列表