资讯动态

Docker部署SRS:快速搭建实时流媒体服务

发布时间:2026/9/16 3:50:52 来源:尧图企业网站定制
项目标题: Docker 部署 SRS轻松搭建实时音视频流媒体平台 项目正文: 关键词: 摘要描述: 你大概率遇到过这种场景流媒体服务器好不容易装完了给前端同事发了个播放地址结果对方那边要么黑屏要么一直转圈。排查半天发现不是配置问题而是最初部署方案就选得别扭。我自己在做过几次自建流媒体平台之后现在的结论非常明确Docker 部署 SRS是目前把实时音视频流媒体平台跑起来最省心的一条路没有之一。SRS 本身是一个开源的实时流媒体服务器全称是 Simple Realtime Server它在流媒体链路里扮演的角色可以理解为一个“协议中转站”推流端把 RTMP、SRT、WebRTC 等协议的数据送进来SRS 把流接收下来再转成 HTTP-FLV、HLS、WebRTC 等不同协议分发给各平台的播放端。你可以用它做直播、做监控大屏、做在线教学也可以作为内部视频分发的中转节点。无论你是有一定基础的后端开发还是刚接触流媒体的小白用 Docker 跑起来 SRS 之后再逐步对照协议知识去加深理解是一个性价比很高的路径。1. 为什么最后我选了 SRS Docker而不是手动编译或 nginx-rtmp很多人刚开始做流媒体时第一反应是去源码编译 SRS或者装个 nginx 加 rtmp 模块。这两条路我都走过各有各的坑。先说结论如果你只是在自己电脑或一台云服务器上做验证Docker 镜像能帮你省掉至少一上午的折腾时间。等你把整套链路跑通再回头决定要不要手动编译也不迟。1.1 SRS 在流媒体链路里到底承担什么角色要理解为什么选 SRS先要弄清楚它在一条直播链路里的位置。最常见的直播场景是这样的主播端用 OBS 或手机推流把视频流推到服务器服务器把流接收下来做协议转换播放端用浏览器、VLC 或小程序拉流观看。这个过程中服务器端软件要解决三个核心问题第一是稳定接收推流不能因为网络抖动就断开第二是协议转换因为推流端常用 RTMP 或 SRT而浏览器播放端通常要 HTTP-FLV 或 HLS移动端 App 可能还要 WebRTC第三是分发效率当几十个、几百个用户同时观看时服务器不能把每一路流都复制一份往外部带宽上怼。SRS 的核心能力正好都覆盖了这三块。它原生支持 RTMP、SRT、HTTP-FLV、HLS、WebRTC 等多种协议而且内置了会话管理、GOP 缓存、集群转发等能力。更关键的是SRS 的配置复杂度在同类产品里算低的默认配置下就能直接跑通一条 RTMP 推流、HTTP-FLV 播放的链路。这一点对新手特别友好。1.2 手动编译的真相不是性能问题是时间成本SRS 官方确实提供了非常详细的编译文档源码编译本身也不复杂脚本执行完等十几分钟就能出二进制。如果你是用一台干净的 Ubuntu 或 CentOS 服务器编译过程中最常翻车的地方在于系统依赖不满足比如缺少 gcc、g、make、patch、unzip 等基础工具或者 OpenSSL 版本不匹配。我踩过的最典型的坑是 CentOS 7 上编译 SRS 4.0系统自带的 OpenSSL 版本偏低configure 阶段就报错。当时我以为是路数不对后来才发现需要先装高版本 OpenSSL然后把 PKG_CONFIG_PATH 指过去。这些操作对老手来说不算什么但对一个只想赶紧把流媒体环境跑起来的人来说非常劝退。而且编译完成并不等于结束SRS 编译产物默认会带上 FFmpeg 依赖和自带工具链目录结构比较复杂新手去理解哪些文件是配置、哪些是日志、哪些可以删又要花不少时间。Docker 镜像解决的就是这部分“环境问题”。镜像里已经把 SRS 编译好、依赖装好、目录结构固定好你只需要关心端口映射和配置挂载。线上环境真出了问题也可以直接删掉容器重新拉起比在一台服务器上反复编译清理要干净得多。1.3 和 nginx-rtmp 对比什么时候才需要换nginx 加 rtmp 模块的方案也很多人用它确实简单配一个 nginx.conf 就能接收 RTMP 推流。但你一旦需要在同一个服务端同时输出 HLS 和 HTTP-FLVnginx 的配置就会变得繁琐。更关键的是WebRTC 低延迟播放是 nginx-rtmp 模块本身做不了的你需要在旁边再搭一个 WebRTC 网关整体架构复杂度立刻上来了。我用一张表简单对比一下三个方案对比项SRSDockerSRS源码编译nginx-rtmp首次部署耗时5 分钟内30 分钟以上15 分钟左右协议覆盖RTMP/FLV/HLS/SRT/WebRTC同左主要以 RTMP 为主配置复杂度低专注流媒体中等中等但扩展协议麻烦升级回滚拉镜像即可重新编译重新编译模块CPU 开销略低于源码运行基准基准如果你只是做一个内部小范围的 RTMP 拉流验证nginx-rtmp 还能应付。但只要你的场景涉及浏览器直接播放、小程序播放、低延迟互动SRS 就是更合适的选择。而用 Docker 部署 SRS等于把门槛又降低了一截。2. 镜像、端口与运行环境动手前先理清这三件事部署之前不要急着执行 docker run先把镜像选型和端口规划搞清楚。这三件事没理清后面配置挂载和网络排障的时候很容易一头雾水。2.1 官方镜像的 Tag 选择别闭眼拉 latestSRS 在 Docker Hub 上有两个常用的镜像仓库老的是ossrs/srs新的官方仓库是srsglobal/srs。我建议直接使用srsglobal/srs这个仓库因为它跟 GitHub Releases 同步更及时。Tag 选择上日常使用首选固定大版本号比如srsglobal/srs:4或srsglobal/srs:5而不是latest。SRS 4 是目前生产环境最稳的一个大版本配置文档和社区资料最多搜问题容易搜到答案。SRS 5 增加了更多 WebRTC 相关的特性和性能优化如果你的主要场景是低延迟 WebRTC 互动可以考虑 5。选择固定版本之后镜像更新逻辑也更清晰先在测试环境拉新版本跑一遍确认没问题再切生产而不是今天 latest 明天 latest某天配置格式变了都不知道。另外顺便说一句SRS 这个项目本身是开源的流媒体服务器社区活跃度一直不错协议支持和 Bug 修复都比较及时。这也是我敢把它作为自建流媒体基础设施的原因。2.2 端口与协议对照每暴露一个端口都要知道为什么SRS 默认涉及四个主要端口每个端口对应一类能力端口协议作用1935TCPRTMP 推流和拉流1985TCPHTTP API 和后台管理接口8080TCPHTTP-FLV/HLS 等 HTTP 流服务8000UDPWebRTC 推流和播放很多新手把容器启动起来之后只知道 1935 是推流的剩下几个端口全映射出去了结果安全组里开了一大堆实际用到的没几个。这里我建议这样理解1935 是必须暴露的因为最常见的推流方式是 RTMPOBS、FFmpeg、部分摄像头都走这个端口。1985 是管理接口主要用来查流状态、调用 API生产环境一般不需要对公网开放甚至可以只绑定在内网。8080 是 HTTP 流服务端口浏览器播放 HTTP-FLV 和 HLS 都靠它。8000 UDP 只有在用到 WebRTC 播放或推流时才需要暴露而且 UDP 端口的安全组配置经常被人漏掉后面我会单独说。理清端口之后你在 docker run 或者 docker-compose 里做端口映射时就能按需开放而不是盲目-p 1935:1935 -p 1985:1985 -p 8080:8080一把梭。3. 三分钟跑通第一路直播流从容器启动到推流播放这个部分我直接给完整命令。你不需要理解所有细节先把链路跑通有了直观感受之后再看后面配置部分会容易很多。3.1 启动一个最简容器先执行这条命令docker run -d --name srs -p 1935:1935 -p 1985:1985 -p 8080:8080 srsglobal/srs:4镜像下载完成后容器会在默认配置下运行。SRS 官方镜像自带一个基础配置开启了大三件RTMP 接收、HTTP-FLV 播放、HLS 切片。启动之后通过 API 接口快速验证一下服务是否正常curl http://localhost:1985/api/v1/versions如果返回的 JSON 里包含major: 4之类的版本信息说明 SRS 已经在正常运行了。这个 API 也是后面排查问题时最常用的探活接口。这里要特别提醒一点一定要用-d放到后台运行别直接前台挂着否则终端一关服务就停了。如果容器启动失败用docker logs srs看日志大部分问题都能在日志里找到明确报错。3.2 推流端FFmpeg 和 OBS 两种最常用方式当 SRS 容器跑起来之后第一步是验证推流。如果本地有一个视频文件最简单的推流命令是ffmpeg -re -i test.mp4 -c copy -f flv rtmp://localhost/live/livestream这条命令里的-re参数值得多说一句它让 FFmpeg 按照视频原始帧率来读取文件相当于模拟真实直播的实时节奏。如果不加这个参数FFmpeg 会以最快速度把文件推完几秒钟就结束了你根本来不及测试播放端。如果你想推摄像头或采集卡画面命令稍微改一下ffmpeg -f v4l2 -i /dev/video0 -c:v libx264 -preset veryfast -tune zerolatency -f flv rtmp://localhost/live/livestream麦克风采集也类似只是要加-f alsa之类的音频输入源。实战中我建议新手先用视频文件推流因为文件推流不依赖硬件设备出错概率最低最适合验证链路。如果你更习惯图形化操作用 OBS 推流也很简单设置里选“自定义”服务填rtmp://你的服务器IP/live串流密钥填livestream然后开始推流。这里应用的底层协议还是 RTMP跟 FFmpeg 走的是同一条链路。3.3 播放端HTTP-FLV、HLS、WebRTC 三种地址怎么拼推流端一旦开始推送播放端就可以拉流了。SRS 默认配置下同一路流会同时输出三种协议地址拼接逻辑如下播放方式地址格式HTTP-FLVhttp://服务器IP:8080/live/livestream.flvHLShttp://服务器IP:8080/live/livestream.m3u8WebRTCwebrtc://服务器IP:8080/live/livestream用 VLC 播放最方便打开 VLC按 CtrlN输入 HTTP-FLV 或 HLS 地址就能直接看到画面。HTTP-FLV 的延迟比 HLS 低很多局域网环境下一般能控制在 1 到 3 秒HLS 因为有切片和缓冲延迟通常在 5 到 10 秒以上。WebRTC 地址在普通 VLC 里是播不了的需要浏览器配合 flv.js 或 WebRTC 播放器才能测。如果你暂时不想折腾前端播放器先用 HTTP-FLV 验证通链路就够了。这一步跑通说明你已经完成了一次完整的“推流-服务端分发-播放”闭环。4. 验证服务与排查问题别只会看“容器在运行”很多人在部署完流媒体服务之后判断正常的标准就是“容器 Status 显示 Up”这其实远远不够。流媒体服务是否真的在工作要看系统里有没有真实流在跑、播放端能不能正常拉到流、切片文件有没有在生成。4.1 用 API 和 ffprobe 确认流真的推上来了容器运行正常但推流端可能根本没连上。这时候最好的验证方式是通过 SRS 的 HTTP API 查询当前流列表curl http://localhost:1985/api/v1/streams/如果返回的 JSON 里能看到类似下面这样的内容说明流已经成功推上来了{ streams: [ { app: live, name: livestream, url: rtmp://localhost/live/livestream } ] }如果列表是空的说明推流端根本没连上 SRS问题大概率出在推流地址、防火墙或网络链路上。另一种更直接的验证方式是使用 ffprobe它是 FFmpeg 家族里的探测工具可以直接拉流检查元数据ffprobe -v error -show_entries streamcodec_name,width,height -f flv http://localhost:8080/live/livestream.flv命令能正常输出视频编码信息和分辨率说明 HTTP-FLV 分发链路没问题。如果卡住不动或报错说明 8080 端口的 HTTP 服务或流在服务端没有正常关联。4.2 日志里的高频故障怎么快速定位SRS 的日志是排查问题最重要的依据。当容器跑在后台时输入docker logs -f srs就可以实时查看 SRS 日志。我建议刚部署完的阶段不要关闭这个窗口推流、播放的时候盯着日志看能非常直观地看到连接建立、流发布、流播放的完整过程。常见的两个高频故障我都会在日志里看到明确特征。第一个是端口被占用典型日志是[ERROR] listen :1935 failed, port is used这通常说明宿主机上已经有一个进程占用了 1935 端口比如之前残留的 nginx 或另一个 SRS 实例。处理方式很简单先查占用端口的进程再决定是停掉旧进程还是换端口映射。用netstat -tlnp | grep 1935就能定位。第二个是推流端频繁断开日志里会看到大量连接超时或断流记录。这种情况优先检查网络尤其是跨公网推流时RTMP 基于 TCP对网络抖动比较敏感。如果推流端和服务器都在国内不同地域延迟高、丢包多就会出现“推上去了过几秒又掉”的情况。4.3 检查 HLS 切片是否正常生成如果你计划用 HLS 播放还需要确认切片文件真的在生成。SRS 4 默认配置下HLS 切片会写到容器内的/usr/local/srs/objs/nginx/html目录。你可以进入容器查看docker exec -it srs ls /usr/local/srs/objs/nginx/html/live/正常情况下这个目录里会看到livestream.m3u8和一堆.ts切片文件。.m3u8是播放索引文件.ts是实际的视频切片。如果推流已经开始、这个目录却是空的说明 HLS 配置没生效或写入路径不对。如果后续做了配置挂载这个目录通常会被挂载到宿主机上。检查挂载目录的文件生成情况是判断 HLS 是否正常的最直接手段。5. 从临时容器升级到可维护部署docker-compose 与配置挂载跑通第一路流之后你大概率会面临一个尴尬情况默认配置能跑但你想调整 HLS 切片长度、开启鉴权、修改日志级别发现根本无从下手。因为容器里的配置文件和宿主机是隔离的每次修改都要进入容器操作容器一删就全没了。5.1 为什么跑通后要第一时间切到配置化部署我见过不少人跑通一次之后就在一台云服务器上持续用默认容器跑了很多天。直到某天需要重启服务器Docker 容器因为不是restart: always策略没有自动拉起整套服务直接消失。这种经历一次就够了。更典型的场景是你要改一个流媒体参数比如把 GOP 缓存关掉、调整 HLS 分片时长如果只用 docker run 起的容器你需要docker exec进容器去修改/usr/local/srs/conf/srs.conf改完还得重启容器。而容器每次删掉重建内部文件又恢复原样等于白改。正确做法是把配置文件通过 volume 挂载到宿主机上让外部可以持久化和版本管理。配置化部署之后你的配置文件可以提交到 Git每次变更可追溯宿主机出了问题拉一个新容器挂载同一份配置就能快速恢复。这才是生产环境该有的状态。5.2 一份直接能用的 docker-compose.yml 和 srs.conf我先给一份最小但完整的 docker-compose 配置。在宿主机建一个目录作为部署根目录比如~/srs-deploy然后在里面创建docker-compose.ymlversion: 3.8 services: srs: image: srsglobal/srs:4 container_name: srs restart: always ports: - 1935:1935 - 1985:1985 - 8080:8080 - 8000:8000/udp volumes: - ./conf/srs.conf:/usr/local/srs/conf/srs.conf - ./logs:/usr/local/srs/objs/logs同时创建配置文件目录conf并在其中新建srs.conflisten 1935; max_connections 1000; daemon off; srs_log_tank console; http_api { enabled on; listen 1985; } http_remux { enabled on; listen 8080; } vhost __defaultVhost__ { hls { enabled on; hls_fragment 6; hls_window 60; } }这份配置里我刻意强调了几个点在启动时容易出问题的地方。daemon off让 SRS 在前台运行这样 Docker 容器不会因为守护进程退出而被杀掉srs_log_tank console让日志输出到标准输出这样docker logs才能看到。这两个配置是容器场景下的必备项缺一个都会让排查问题变成地狱模式。启动方式也很简单cd ~/srs-deploy docker compose up -d然后还是用前面的 API 验证方式检查服务状态。如果一切正常你会看到日志里开始输出rtmp server listen on 1935等字样。5.3 改配置后的几个注意点配置切到宿主机之后改配置变成一件平常事但有三个注意点值得说清楚。第一SRS 的配置文件语法比较敏感每个配置项后面必须有分号花括号的位置也有限制。改完之后如果容器一直启动失败第一反应应该是用docker logs srs看输出配置语法错误通常会在启动日志里明确报出。第二挂载配置文件时要注意容器内路径必须正确。SRS 官方镜像的工作目录是/usr/local/srs默认配置路径是/usr/local/srs/conf/srs.conf你在 volume 里挂载时冒号右半边必须严格写成这个路径。挂错路径的情况下容器可能还会用镜像内置的默认配置启动造成“我改了配置但没生效”的错觉。第三修改 HLS 输出路径时要确保容器内对应目录有写权限。挂载目录如果权限不对SRS 启动时不会直接报错但切片文件写不进去播放端拉流会一直转圈。我习惯在挂载之后用docker exec -it srs ls检查一下目标目录能否正常访问。6. 生产环境不能忽略的三件事鉴权、安全组和低延迟参数跑通了、配置也挂载了接下来就是生产环境真正考验人的地方。公网环境下跑一个没有任何鉴权的流媒体服务和把你的服务器裸奔在互联网上没多大区别。任何人都可以往你服务器上推流不仅消耗带宽还可能产生内容风险。6.1 推流鉴权别让公共服务器变成别人的直播源SRS 提供 push 鉴权机制最常用的方式是 HTTP 回调鉴权。原理是当有推流端连上来时SRS 会把流信息通过 HTTP 请求发送到你指定的鉴权服务器鉴权服务器返回允许或拒绝SRS 再决定是否接受这路推流。在srs.conf的 vhost 里加入类似这样的配置vhost __defaultVhost__ { http_hooks { enabled on; on_publish http://your-auth-server/api/v1/srs/auth; } }具体回调参数格式 SRS 官方文档写得很清楚核心就是对比推流 URL 里的参数和你的业务系统校验结果。如果你的场景暂时没有独立鉴权服务也可以在推流地址里带一个固定密钥在回调接口里做字符串比对实现成本很低。我建议即便在测试环境也至少把 1985 这个管理端口从公网屏蔽掉。因为 SRS 的 HTTP API 默认没有鉴权外部任何人访问 1985 端口都能通过/api/v1/streams/看到你服务器上正在直播的流列表这显然不是想暴露的信息。6.2 端口暴露范围和安全组规划Docker 端口映射不等于安全组规则。很多云服务器上Docker 的-p 1935:1935只负责把容器端口映射到宿主机能不能从公网访问还要看云服务商的安全组和系统防火墙。生产环境我的建议是分层控制1935 端口只对推流端 IP 或网段开放如果可以限制到已知的推流来源。8080 端口可以对公网开放因为播放端来源不可控。1985 端口只绑定内网或本机禁止公网访问。8000 UDP 端口按需开放不要默认打开。另一个容易被忽略的细节是 Docker 本身的端口绑定地址。如果你在 docker run 里写的是-p 127.0.0.1:1985:1985那么只有宿主机本机可以访问 1985 端口公网一律连不上。这有时候是好事有时候也会让你误判服务状态。6.3 低延迟和稳定性的关键参数如果你追求比较低的直播延迟有几个参数可以调。SRS 默认配置更多是兼顾兼容性真要跑低延迟场景需要在配置里做调整。第一个是 HLS 切片时长hls_fragment默认是 6 秒。切片时间越长播放端加载索引后需要缓冲的数据越多延迟自然越高。但切得太短又会增加服务器切片写入压力和播放端请求频率。一般 2 到 4 秒是比较平衡的选择。第二个是gop_cache默认是开启的。这个参数的意思是缓存当前 GOP关键帧间隔的数据新播放端接入时可以快速从关键帧开始播放实现“秒开”。但代价是延迟会增加一点。低延迟场景下可以考虑关闭vhost __defaultVhost__ { gop_cache off; }第三个是 TCP 相关的调优参数比如开启tcp_nodelay减少小包堆积带来的延迟抖动。这些参数在 SRS 文档里都有说明配置方式也比较统一改完之后重启容器即可。7. 我踩过的坑和一些长期运维心得最后这部分是实际操作中的教训汇总。每一个坑都真实发生过写出来希望帮你少走弯路。7.1 外网连不上第一排查清单“本机推流播放都正常换了台机器就访问不了了”是出现频率最高的问题。这个问题的排查顺序应该是先查云安全组是否放行了对应端口再查系统防火墙最后查 Docker 端口映射绑定地址。有一次我排查了很久最后发现是云服务器安全组只放行了 1935没放行 8080导致播放端访问不了 HTTP-FLV。那一次的经历让我养成了一个习惯任何一次部署都把端口清单写成一个表格对照安全组一条条核对绝不依赖记忆。7.2 理解 CUID 和流地址的映射关系在 SRS 日志里频繁出现 CUID 这个词它指的是 Connection Unique ID即每个客户端连接的唯一标识。刚开始看日志时看到一大串 CUID 很容易懵但其实只要知道它是连接的 ID 就足够了。真正需要注意的是流的 URL 映射关系。SRS 定义一个流的位置靠三要素路径中的 app、流名称 stream以及对应的 vhost。默认配置下 vhost 是__defaultVhost__app 是livestream 是livestream。这三要素必须一致推流和播放才能对上。比如你用rtmp://ip/live/livestream推流播放地址就必须是http://ip/live/livestream.flv或http://ip/live/livestream.m3u8中间不能换 app 或 stream 名称。很多新手把 HLS 地址写成了http://ip/hls/livestream.m3u8结果一直播不出来原因就是 app 从live变成了hls和推流路径对不上了。7.3 Docker 日志和配置文件的运维习惯长期跑 SRS 之后运维习惯比技术细节更重要。我对所有流媒体容器的统一建议有三条。第一Docker 的日志驱动一定要限制大小。默认情况下容器日志会无限增长SRS 在实况直播场景下的日志量不小跑几个月能把磁盘塞满。docker-compose 里可以这样限制logging: driver: json-file options: max-size: 50m max-file: 3第二srs.conf 一定要纳入版本管理。流媒体配置的改动往往不是频繁的但一旦改错了想快速回滚到上一个可用版本没有版本管理就只能凭记忆改回来。第三升级前先看版本差异。如果要从 SRS 4 升级到 SRS 5不要直接切换镜像 Tag 了事一定要先看官方文档里的配置变更说明特别是 WebRTC 相关配置。我就遇到过从 4.x 切到 5.x 后某些配置项写法变了启动直接报错的情况。7.4 一条很实用的收尾建议如果你也打算在生产环境跑 SRS我建议在正式上线前做一次全链路延迟测试推流端放一个毫秒级计时器画面播放端拍照对比延迟。这个测试能同时检验网络环境、协议选择和服务器参数调优的效果。只有亲眼看到延迟数据你才知道当前配置是否真的适合你的业务场景。大多数人第一次测出来的结果都会和预期差很多而这恰好就是调优的开始。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价