RTMP 协议精讲 / 11 - Docker 部署
Docker 部署流媒体服务
11.1 为什么使用 Docker
| 优势 | 说明 |
|---|---|
| 环境一致性 | 开发/测试/生产环境完全一致 |
| 快速部署 | 一条命令启动完整服务 |
| 版本管理 | 轻松切换和回滚版本 |
| 资源隔离 | CPU/内存/网络隔离 |
| 可扩展 | 轻松增加实例 |
| 可复现 | 部署过程文档化 |
11.2 SRS Docker 快速启动
11.2.1 单命令启动
# 启动 SRS(最简方式)
docker run --rm \
-p 1935:1935 \
-p 1985:1985 \
-p 8080:8080 \
ossrs/srs:5
# 推流测试
ffmpeg -re -i test.mp4 -c copy -f flv \
rtmp://localhost:1935/live/test
# 播放测试
ffplay rtmp://localhost:1935/live/test
ffplay http://localhost:8080/live/test.flv
ffplay http://localhost:8080/live/test.m3u8
11.2.2 使用自定义配置
# 创建配置文件
mkdir -p conf
cat > conf/docker.conf << 'EOF'
listen 1935;
max_connections 1000;
srs_log_tank console;
http_api {
enabled on;
listen 1985;
}
http_server {
enabled on;
listen 8080;
}
vhost __defaultVhost__ {
hls {
enabled on;
hls_fragment 2;
hls_window 10;
}
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}
}
EOF
# 挂载配置文件启动
docker run --rm \
-p 1935:1935 \
-p 1985:1985 \
-p 8080:8080 \
-v $(pwd)/conf/docker.conf:/usr/local/srs/conf/docker.conf \
ossrs/srs:5 ./objs/srs -c conf/docker.conf
11.3 Docker Compose 基础配置
11.3.1 项目结构
srs-docker/
├── docker-compose.yml
├── conf/
│ ├── srs.conf
│ └── edge.conf
├── web/
│ └── index.html
└── data/
├── recordings/
└── hls/
11.3.2 docker-compose.yml
version: '3.8'
services:
# SRS 流媒体服务器
srs:
image: ossrs/srs:5
container_name: srs-server
ports:
- "1935:1935" # RTMP
- "1985:1985" # HTTP API
- "8080:8080" # HTTP Server
volumes:
- ./conf/srs.conf:/usr/local/srs/conf/docker.conf
- ./data/hls:/usr/local/srs/objs/nginx/html
- ./data/recordings:/data/recordings
command: ./objs/srs -c conf/docker.conf
restart: unless-stopped
networks:
- srs-net
# HLS Web 服务(可选)
nginx:
image: nginx:alpine
container_name: srs-nginx
ports:
- "80:80"
volumes:
- ./data/hls:/usr/share/nginx/html:ro
- ./web:/usr/share/nginx/html/web:ro
depends_on:
- srs
restart: unless-stopped
networks:
- srs-net
networks:
srs-net:
driver: bridge
11.3.3 SRS 配置文件
# conf/srs.conf
listen 1935;
max_connections 1000;
srs_log_tank console;
http_api {
enabled on;
listen 1985;
}
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}
vhost __defaultVhost__ {
# 最小延迟
min_latency on;
# GOP Cache
gop_cache on;
gop_cache_max_frames 2500;
# HLS 配置
hls {
enabled on;
hls_fragment 2;
hls_window 10;
hls_path ./objs/nginx/html;
hls_m3u8_file [app]/[stream].m3u8;
hls_ts_file [app]/[stream]-[seq].ts;
hls_cleanup on;
hls_dispose 30;
}
# HTTP-FLV
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}
# DVR 录制
dvr {
enabled on;
dvr_path /data/recordings/[app]/[stream].[timestamp].flv;
dvr_plan session;
dvr_wait_keyframe on;
}
}
11.3.4 启动与管理
# 启动所有服务
docker-compose up -d
# 查看状态
docker-compose ps
# 查看日志
docker-compose logs -f srs
# 停止所有服务
docker-compose down
# 重启 SRS
docker-compose restart srs
11.4 多实例集群部署
11.4.1 Origin + Edge 集群
# docker-compose-cluster.yml
version: '3.8'
services:
# Origin 源站
srs-origin:
image: ossrs/srs:5
container_name: srs-origin
ports:
- "1935:1935"
- "1985:1985"
volumes:
- ./conf/origin.conf:/usr/local/srs/conf/docker.conf
command: ./objs/srs -c conf/docker.conf
restart: unless-stopped
networks:
srs-net:
ipv4_address: 172.20.0.10
# Edge 边缘节点 1
srs-edge-1:
image: ossrs/srs:5
container_name: srs-edge-1
ports:
- "1936:1935"
- "1986:1985"
- "8081:8080"
volumes:
- ./conf/edge.conf:/usr/local/srs/conf/docker.conf
command: ./objs/srs -c conf/docker.conf
depends_on:
- srs-origin
restart: unless-stopped
networks:
srs-net:
ipv4_address: 172.20.0.11
# Edge 边缘节点 2
srs-edge-2:
image: ossrs/srs:5
container_name: srs-edge-2
ports:
- "1937:1935"
- "1987:1985"
- "8082:8080"
volumes:
- ./conf/edge.conf:/usr/local/srs/conf/docker.conf
command: ./objs/srs -c conf/docker.conf
depends_on:
- srs-origin
restart: unless-stopped
networks:
srs-net:
ipv4_address: 172.20.0.12
networks:
srs-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24
11.4.2 Origin 配置
# conf/origin.conf
listen 1935;
max_connections 1000;
http_api {
enabled on;
listen 1985;
}
http_server {
enabled on;
listen 8080;
}
vhost __defaultVhost__ {
gop_cache on;
hls {
enabled on;
hls_fragment 2;
hls_window 10;
}
}
11.4.3 Edge 配置
# conf/edge.conf
listen 1935;
max_connections 1000;
http_api {
enabled on;
listen 1985;
}
http_server {
enabled on;
listen 8080;
}
vhost __defaultVhost__ {
cluster {
mode remote;
origin 172.20.0.10:1935;
}
gop_cache on;
hls {
enabled on;
hls_fragment 2;
hls_window 10;
}
}
11.5 完整生产环境配置
11.5.1 带监控的生产配置
# docker-compose-production.yml
version: '3.8'
services:
# SRS 流媒体服务器
srs:
image: ossrs/srs:5
container_name: srs-server
ports:
- "1935:1935"
- "1985:1985"
- "8080:8080"
volumes:
- ./conf/srs.conf:/usr/local/srs/conf/docker.conf
- ./data/hls:/data/hls
- ./data/recordings:/data/recordings
command: ./objs/srs -c conf/docker.conf
restart: unless-stopped
deploy:
resources:
limits:
cpus: '4.0'
memory: 4G
reservations:
cpus: '2.0'
memory: 2G
networks:
- srs-net
# Prometheus 指标收集
prometheus:
image: prom/prometheus:latest
container_name: srs-prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
restart: unless-stopped
networks:
- srs-net
# Grafana 监控面板
grafana:
image: grafana/grafana:latest
container_name: srs-grafana
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
environment:
GF_SECURITY_ADMIN_PASSWORD: admin123
restart: unless-stopped
networks:
- srs-net
# Nginx 反向代理
nginx:
image: nginx:alpine
container_name: srs-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/ssl:/etc/nginx/ssl
- ./data/hls:/usr/share/nginx/html:ro
depends_on:
- srs
restart: unless-stopped
networks:
- srs-net
volumes:
prometheus-data:
grafana-data:
networks:
srs-net:
driver: bridge
11.5.2 Nginx 反向代理配置
# nginx/nginx.conf
events {
worker_connections 1024;
}
http {
# HLS 分发
server {
listen 80;
server_name live.example.com;
# HLS
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /usr/share/nginx/html;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
# HTTP-FLV
location /live {
add_header Access-Control-Allow-Origin *;
add_header Cache-Control no-cache;
proxy_pass http://srs:8080;
}
# SRS API 代理
location /api {
proxy_pass http://srs:1985;
}
# 监控面板
location /grafana {
proxy_pass http://grafana:3000;
}
}
}
11.5.3 Prometheus 配置
# prometheus/prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'srs'
metrics_path: /api/v1/metrics
static_configs:
- targets: ['srs:1985']
11.6 部署脚本
一键部署脚本
#!/bin/bash
# deploy.sh - SRS 一键部署脚本
set -e
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$PROJECT_DIR"
echo "🚀 开始部署 SRS 流媒体服务..."
# 创建必要目录
mkdir -p conf data/hls data/recordings nginx prometheus
# 检查配置文件
if [ ! -f conf/srs.conf ]; then
echo "📝 生成默认配置..."
cat > conf/srs.conf << 'EOF'
listen 1935;
max_connections 1000;
srs_log_tank console;
http_api { enabled on; listen 1985; }
http_server { enabled on; listen 8080; }
vhost __defaultVhost__ {
min_latency on;
gop_cache on;
hls {
enabled on;
hls_fragment 2;
hls_window 10;
}
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}
}
EOF
fi
# 启动服务
echo "🐳 启动 Docker 服务..."
docker-compose up -d
# 等待服务启动
echo "⏳ 等待服务启动..."
sleep 5
# 验证服务
echo "🔍 验证服务状态..."
if curl -s http://localhost:1985/api/v1/summaries > /dev/null; then
echo "✅ SRS 服务正常"
else
echo "❌ SRS 服务异常,请检查日志"
docker-compose logs srs
exit 1
fi
# 获取本机 IP
LOCAL_IP=$(hostname -I | awk '{print $1}')
echo ""
echo "========================================="
echo " SRS 流媒体服务部署完成!"
echo "========================================="
echo ""
echo " 推流地址: rtmp://${LOCAL_IP}:1935/live/{stream_key}"
echo " RTMP 播放: rtmp://${LOCAL_IP}:1935/live/{stream_key}"
echo " HTTP-FLV: http://${LOCAL_IP}:8080/live/{stream_key}.flv"
echo " HLS: http://${LOCAL_IP}:8080/live/{stream_key}.m3u8"
echo " API 文档: http://${LOCAL_IP}:1985"
echo ""
echo " 常用命令:"
echo " 查看日志: docker-compose logs -f srs"
echo " 停止服务: docker-compose down"
echo " 重启服务: docker-compose restart"
echo ""
11.7 流媒体架构图
11.7.1 单机架构
┌──────────────────────────────────────────────────────┐
│ Docker Host │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ SRS Server │ │ Nginx │ │ Grafana │ │
│ │ :1935(RTMP) │ │ :80(HTTP) │ │ :3000 │ │
│ │ :1985(API) │ │ │ │ │ │
│ │ :8080(HTTP) │ │ │ │ │ │
│ └──────┬──────┘ └──────┬──────┘ └─────────────┘ │
│ │ │ │
│ └────────┬───────┘ │
│ │ │
│ ┌─────┴─────┐ │
│ │ 容器网络 │ │
│ └───────────┘ │
└──────────────────────────────────────────────────────┘
11.7.2 集群架构
┌────────────────────┐
│ Load Balancer │
│ (Nginx/HAProxy) │
└─────────┬──────────┘
│
┌─────┴─────┐
│ 公网 │
└─────┬─────┘
│
┌─────┴─────────────────────────────────┐
│ Docker Swarm / K8s │
│ │
│ ┌────────────┐ ┌────────────┐ │
│ │ Origin │ │ Origin │ │
│ │ (Primary) │ │ (Backup) │ │
│ └─────┬──────┘ └─────┬──────┘ │
│ └────────┬──────┘ │
│ │ │
│ ┌────────────┼────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │Edge 1│ │Edge 2│ │Edge 3│ │
│ └──────┘ └──────┘ └──────┘ │
│ │
│ ┌──────────────────────────────┐ │
│ │ Shared Storage │ │
│ │ (HLS/Recordings/Config) │ │
│ └──────────────────────────────┘ │
└────────────────────────────────────────┘
11.8 常用运维命令
# 查看容器状态
docker-compose ps
# 查看实时日志
docker-compose logs -f srs
# 查看资源使用
docker stats srs-server
# 进入容器
docker exec -it srs-server bash
# 查看 SRS 版本
docker exec srs-server ./objs/srs -v
# 备份配置
tar czf srs-backup-$(date +%Y%m%d).tar.gz conf/ docker-compose.yml
# 清理 HLS 缓存
docker exec srs-server find /data/hls -name "*.ts" -mmin +60 -delete
# 查看网络连接
docker exec srs-server netstat -tlnp
注意事项
- 端口冲突:确保宿主机端口未被占用(1935, 8080, 1985)
- 磁盘空间:HLS 分片和录制文件会快速占用磁盘,需要定期清理
- ulimit 设置:高并发场景需在 docker-compose 中配置
ulimits - GPU 转码:需要 GPU 转码时,需挂载设备(
--device /dev/dri或--gpus all) - 时区设置:容器内时间可能不正确,添加
-e TZ=Asia/Shanghai或挂载/etc/localtime - 日志管理:配置日志轮转避免日志文件撑满磁盘
扩展阅读
上一章:10 - 流中转与分发 下一章:12 - 最佳实践 — RTMP 低延迟优化、安全与监控