
一次跑通Docker 部署 Janus WebRTC Server 的完整流程【免费下载链接】janus-gatewayJanus WebRTC Server项目地址: https://gitcode.com/GitHub_Trending/ja/janus-gateway这篇教程带你完成 Janus WebRTC Server 的 Docker 部署构建镜像、一键拉起、验证媒体链路、调优到生产可用。照着操作30 分钟左右你的服务器上就会跑起一台 WebRTC 媒体服务器。学完你将得到一份可构建的双阶段 Janus Dockerfile 与最小可运行 compose 配置一套逐条验证 API 与媒体链路的检查清单生产环境配置要点API 密钥、NAT 映射与资源限制先花一分钟看清全貌Janus 是一个开源的 WebRTC 媒体服务器客户端通过 HTTP 或 WebSocket 下发信令服务器按插件Echo Test、视频会议室、音频会议等建立会话真正的音视频流走 UDP 媒体端口。直接源码编译它要手动装齐 GLib、libnice、libsrtp2、libwebsockets 等十余项依赖还要处理版本冲突这正是 Janus 容器化的价值所在——它一次性解决了三个问题依赖冲突依赖版本被镜像固化不随发行版更新漂移、环境漂移开发与生产跑同一份镜像、迁移成本换机器只需重新docker run无需重新编译。维度源码编译容器部署耗时约 30–60 分钟装依赖、编译、排错首次构建约 10 分钟之后秒级启动依赖手动管理十余个库版本冲突常见依赖固定在镜像层可复现回滚重新编译或手工恢复库文件保留旧镜像 tag切回即可第 1 步备齐地基Docker 与 Compose开始写配置之前先确认宿主机具备运行条件Docker 20.10 以上、Compose v2 插件docker compose子命令形式。两者通常随发行版或官方安装脚本一起就位这里只做验证docker --version # 预期Docker version 20.10 docker compose version # 预期Compose version v2.x第 2 步打造镜像Dockerfile 的设计思路这段 Janus Dockerfile 教程的核心思路是双阶段构建第一个阶段builder装编译器和全部-dev头文件库产出二进制与配置模板第二个阶段只保留运行时共享库。这样最终镜像里没有编译器、头文件和源码体积更小暴露的攻击面也更小。下面这份精简 Dockerfile 你基本可以原样使用需要改的只有第②步的仓库地址FROM ubuntu:20.04 AS builder ENV DEBIAN_FRONTENDnoninteractive # ① 编译依赖工具链 GLib/libnice/libsrtp2 等 Janus 全部硬依赖 RUN apt-get update apt-get install -y --no-install-recommends \ build-essential pkg-config libtool automake \ libmicrohttpd-dev jansson-dev libssl-dev libsrtp2-dev \ libsofia-sip-ua-dev libglib2.0-dev libopus-dev libogg-dev \ libcurl4-openssl-dev libnice-dev libwebsockets-dev libconfig-dev \ rm -rf /var/lib/apt/lists/* # ② 获取源码并生成构建脚本 RUN git clone https://gitcode.com/GitHub_Trending/ja/janus-gateway /usr/src/janus \ cd /usr/src/janus sh autogen.sh # ③ configure启用 WebSockets/REST/数据通道/后处理禁用不用的消息队列 RUN cd /usr/src/janus ./configure --prefix/opt/janus \ --enable-websockets --enable-rest --enable-data-channels \ --enable-post-processing --disable-rabbitmq --disable-mqtt \ make -j$(nproc) make install make configs FROM ubuntu:20.04 # ④ 运行层只装共享库包名与构建层版本严格对应 RUN apt-get update apt-get install -y --no-install-recommends \ libmicrohttpd12 libjansson4 libssl1.1 libsrtp2-1 libsofia-sip-ua0 \ libglib2.0-0 libopus0 libogg0 libcurl4 libconfig9 libnice4 libwebsockets8 \ rm -rf /var/lib/apt/lists/* COPY --frombuilder /opt/janus /opt/janus EXPOSE 8088 8188 10000-10200/udp ENTRYPOINT [/opt/janus/bin/janus]逐段说明① 依赖清单决定了最终能力去掉libwebsockets-dev就没有 WebSocket 传输去掉libsrtp2-dev则 SRTP 加密媒体无从谈起② 用git clone拉取源码后必须跑autogen.sh生成configure③configure选项里--enable-websockets对应 8188 端口--disable-rabbitmq/--disable-mqtt砍掉不用的消息队列集成编译更快、运行层更小④ 运行层包名必须与 focal 仓库中的构建层版本一致。启动行为交给一个短小的入口脚本它负责首次启动时生成配置、按环境改写公网 IP 与媒体端口段#!/bin/bash set -e # 首次启动把示例配置展开到挂载的 conf 目录 [ -f /opt/janus/conf/janus.jcfg ] || cp /opt/janus/etc/janus/*.jcfg.sample /opt/janus/conf/ # 1:1 NAT 场景改写公网 IP可选通过环境变量传入 [ -n $NAT_1_1 ] sed -i s|#nat_1_1_mapping .*|nat_1_1_mapping \$NAT_1_1\| /opt/janus/conf/janus.jcfg # 固定媒体端口段为 UDP 10000-10200与 EXPOSE 保持一致 sed -i s|#rtp_port_range .*|rtp_port_range 10000-10200| /opt/janus/conf/janus.jcfg exec /opt/janus/bin/janus --configs-folder/opt/janus/conf \ --log-file/opt/janus/logs/janus.log --debug-level${DEBUG_LEVEL:-4} $保存为docker-entrypoint.sh后用一条命令构建镜像docker build -t janus-gateway:latest .第 3 步一键拉起从最小配置到生产配置先给最小可运行配置。它刻意做了两件事用network_mode: host避开端口映射和媒体地址重写把配置目录挂出来让你可以随时改services: janus: image: janus-gateway:latest container_name: janus restart: always network_mode: host # 媒体流直出宿主机网卡无需 NAT 重写 environment: - DEBUG_LEVEL4 # 日志级别 4debug生产建议降到 2 volumes: - ./janus-conf:/opt/janus/conf - ./janus-logs:/opt/janus/logs - ./janus-recordings:/opt/janus/recordings开发场景开发机不需要任何额外动作mkdir -p janus-conf janus-logs janus-recordings建好目录后执行docker compose up -d入口脚本会自动从示例配置生成janus.jcfg。想调试就保持DEBUG_LEVEL4日志写进janus-logs/改配置后docker compose restart janus生效。生产场景Janus 生产环境配置与开发版的差异集中在四处直接体现在这份 compose 里services: janus: image: janus-gateway:latest restart: always network_mode: host environment: - DEBUG_LEVEL2 # 降低日志量减少磁盘 IO - NAT_1_1your-public-ip # 云主机 1:1 NAT 时填公网 IP否则留空 command: --apisecretyour-secret # API 请求必须携带密钥 volumes: - ./janus-conf:/opt/janus/conf - ./janus-logs:/opt/janus/logs网络模式生产同样推荐 host 模式若坚持 bridge 模式必须把 8088/8188 与 UDP 10000–10200 全部映射出来并确认地址重写正确。API 密钥--apisecret让每个 HTTP/WebSocket 请求都必须带?apisecret...等价于给你的媒体服务器加了一道门禁更细粒度可用配置里的token_auth签发令牌。NAT 映射容器在云主机 1:1 NAT 后面时NAT_1_1让 Janus 对外宣告公网地址而不是内网 IP。挂载目录配置、日志、录制三类目录分别挂载镜像更新不丢数据。⚠️ 切记不要把your-secret提交进代码仓库。第 4 步验证它真的在跑服务起来和媒体链路通了是两回事按下面四条清单逐一确认进程docker exec -it janus ps aux | grep janus预期结果存在一个bin/janus进程无 crash 重启记录可加看docker logs janus --tail 50。端口ss -lntup | grep -E 8088|8188预期结果8088HTTP API与 8188WebSocket API均在监听媒体 UDP 端口是按需绑定的建流后用ss -ulnp | grep 100能看到 10000 段内的绑定。APIcurl -s http://127.0.0.1:8088/janus/info预期结果{ janus: server_info, version: 1.0.x, plugins: [janus.plugin.echotest, janus.plugin.videoroom], transports: [janus.transport.http, janus.transport.websockets] }plugins里应能看到编译时启用的插件transports里应含 http 与 websockets。 4.演示页把仓库里的 html/demos 目录拷到任意静态服务器浏览器打开demos/echotest.html点 Start。 预期结果几秒内能听到自己声音的回放——这一刻说明信令、ICE、SRTP 媒体全链路都通了。进阶更稳更快基础链路通了之后这三处是生产调优的高频动作。资源限制防止单容器吃满宿主机deploy: resources: limits: { cpus: 4, memory: 4G } reservations: { cpus: 2, memory: 2G }UDP 媒体是典型的大包高吞吐场景调大 socket 缓冲区放在同一份 compose 的 service 下sysctls: - net.core.rmem_max26214400 - net.core.wmem_max26214400日志文件会持续增长给宿主机加一个 logrotate 规则/etc/logrotate.d/janus/path/to/janus-logs/*.log { daily rotate 7 compress create 0640 root root }踩坑速查现象原因解法验证命令ICE 连接超时建流卡死STUN 服务器不可达或宿主机 UDP 出方向被封把nat:stun_server换成可达地址如 stun.aliyun.com:3478nc -zvu stun.aliyun.com 3478媒体端口不通有信令无媒体UDP 10000–10200 未放行或rtp_port_range与防火墙不一致安全组放行该 UDP 段且与janus.jcfg中media:rtp_port_range保持同一区间ss -ulnp | grep 100NAT 穿透失败连接频繁中断1:1 NAT 下宣告的是内网 IP设nat_1_1_mapping为公网 IPcompose 传NAT_1_1grep nat_1_1 janus-conf/janus.jcfg容器资源占用高日志级别过高或并发流过多DEBUG_LEVEL降到 2并用deploy.resources限制 CPU/内存docker stats janus把镜像、配置、验证三件事各自落到一份可复用文件里Janus 容器化部署的工作就基本收尾了。后续如果要支撑更大的并发或对外暴露服务方向是接入 TURN 服务器处理对称型 NAT以及在 API 层前面加一层鉴权与限流网关。【免费下载链接】janus-gatewayJanus WebRTC Server项目地址: https://gitcode.com/GitHub_Trending/ja/janus-gateway创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考