LiveKit 是一个开源 WebRTC SFU。简单说,它负责房间、信令、音视频转发、数据通道,以及客户端之间的实时连接。你可以直接用 LiveKit Cloud,也可以把 LiveKit Server 跑在自己的服务器上。自部署的好处很直接:数据、网络、地域、成本和扩展方式都由你控制。代价也同样直接:TLS、TURN、Redis、端口、防火墙、升级和监控,都要自己管。
这篇教程按生产落地来写。目标不是“本地跑起来看看”,而是让你能在一台云服务器或 Kubernetes 集群里部署一个能给真实用户使用的 LiveKit。
资料来源主要来自 LiveKit 官方文档、官方 config-sample.yaml、GitHub Release 和 Helm 文档。
适合谁读
你适合自部署 LiveKit,如果你有这些需求:
- 想把音视频服务放在自己的云账号或机房里
- 对数据驻留、内网访问或合规有要求
- 已经有 Kubernetes、Prometheus、日志系统和对象存储
- 想控制 WebRTC 的端口、TURN、TLS、带宽和扩容策略
- 需要配合自部署的 Agents、Ingress、Egress 或 SIP 服务
如果你只是做一个 MVP,或者团队没人愿意维护 WebRTC 基础设施,LiveKit Cloud 会省很多事。
LiveKit 自部署的核心组件
最小生产部署通常包含这些东西:
- LiveKit Server:核心 SFU 和 API 服务
- Redis:房间状态、节点发现、分布式消息总线
- HTTPS 入口:给客户端连接
wss://livekit.example.com - TURN:提高复杂网络环境下的连通率,尤其是公司网络、VPN、严格防火墙
- 防火墙规则:开放 WebRTC 所需端口
- 监控:Prometheus 指标、日志、健康检查
可选组件:
- Egress:录制房间、导出单轨、推流到 RTMP 平台
- Ingress:接入 RTMP、WHIP、SRT 等外部媒体源
- SIP Server:电话呼入呼出
- Agents:AI Agent worker,连接到你的自部署 LiveKit Server
LiveKit 自部署不是只起一个容器。真正麻烦的地方在网络。
部署路线怎么选
常见有三条路线。
1. 本地开发
适合 SDK 开发、验证 token、跑 demo。
# macOS
brew update && brew install livekit
# Linux
curl -sSL https://get.livekit.io | bash
# 开发模式启动
livekit-server --dev
开发模式会使用固定密钥:
API key: devkey
API secret: secret
默认只监听 127.0.0.1:7880。如果你想让局域网里的手机或其他机器访问,可以这样启动:
livekit-server --dev --bind 0.0.0.0
注意:开发模式不要放到公网。
2. 单机 VM + Docker Compose + Caddy
这是多数小团队最容易落地的方式。官方推荐用生成器生成配置,它会给你生成 Caddy、Docker Compose、LiveKit、Redis 和初始化脚本。
适合:
- 一台云服务器起步
- 有域名
- 想自动申请 TLS 证书
- 暂时不想维护 Kubernetes
3. Kubernetes + Helm
适合已经有集群的团队。LiveKit 官方提供 Helm chart,可以部署分布式 LiveKit Server、Service 和 Ingress。
但有一个关键点:LiveKit Pod 需要直接访问宿主机网络,通常会使用 host networking。WebRTC 的 UDP/TCP 媒体端口会直接打到节点上,所以通常一个节点只能跑一个 LiveKit Pod。Kubernetes 可以做,但不要把它当普通 Web 服务来部署。
另外,LiveKit 官方明确不建议部署在 serverless 或 private cluster 上。额外 NAT 层会让 WebRTC 变得很难排查。
准备域名
生产部署至少准备一个主域名:
livekit.example.com
客户端连接时会使用:
wss://livekit.example.com
如果你启用 TURN/TLS,建议再准备一个 TURN 域名:
turn.example.com
两个域名都要解析到你的服务器或负载均衡器。证书必须是受信任 CA 签发的证书,自签证书不适合给浏览器和移动端 SDK 用。
如果使用 Caddy,证书可以自动申请。前提是:
- DNS 已经指向服务器
- 80 和 443 端口可访问
- 云厂商安全组没有挡住入站流量
单机 VM 部署
前提条件
你需要:
- 一台 Linux VM,建议 Ubuntu 或 Amazon Linux
- 一个域名,并能添加子域名 DNS 记录
- Docker / Docker Compose,官方生成脚本可以帮你装
- 公网 IP
- 云安全组或防火墙配置权限
生成配置
在本地开发机运行官方生成器:
docker pull livekit/generate
docker run --rm -it -v $PWD:/output livekit/generate
生成器会问你域名、是否启用 Ingress/Egress 等选项。完成后会在当前目录生成一个以域名命名的文件夹,里面通常有:
caddy.yaml
docker-compose.yaml
livekit.yaml
redis.conf
init_script.sh
cloud_init.xxxx.yaml
如果云厂商支持 cloud-init,最省事的方式是创建 VM 时把 cloud_init.xxxx.yaml 粘到 User Data 里。机器启动后会自动安装 Docker、写入配置、启动服务。
如果不用 cloud-init,也可以把 init_script.sh 拷到服务器上执行:
scp init_script.sh root@your-server:/root/
ssh root@your-server
chmod +x init_script.sh
sudo ./init_script.sh
脚本完成后,一般会把配置放到:
/opt/livekit
并创建 systemd 服务:
systemctl status livekit-docker
systemctl stop livekit-docker
systemctl start livekit-docker
单机 VM 需要开放的端口
如果按官方 VM 方案部署,至少开放:
80/TCP:证书申请,HTTP-01 challenge443/TCP:HTTPS、WebSocket、TURN/TLS7881/TCP:WebRTC over TCP3478/UDP:TURN/UDP50000-60000/UDP:WebRTC UDP 媒体端口
如果启用 Ingress:
1935/TCP:RTMP Ingress7885/UDP:WHIP Ingress WebRTC
如果启用 SIP:
5060/UDP和5060/TCP:SIP signaling5061/TCP:SIP TLS10000-20000/UDP:SIP RTP 媒体端口
WebRTC 最怕“服务启动了,但 UDP 没通”。如果用户能进房间但没有声音、视频黑屏、连接很慢,第一件事就是查 UDP 端口和候选地址。
生产配置文件怎么写
生产环境建议使用 YAML 配置文件,而不是一堆命令行参数。LiveKit 支持:
livekit-server --config /path/to/livekit.yaml
也支持把 YAML 内容放进 LIVEKIT_CONFIG 环境变量。
一个简化的生产配置如下:
port: 7880
log_level: info
rtc:
tcp_port: 7881
port_range_start: 50000
port_range_end: 60000
use_external_ip: true
redis:
address: redis.example.internal:6379
keys:
your_api_key: your_api_secret
turn:
enabled: true
domain: turn.example.com
tls_port: 3478
# prometheus_port: 6789
几个字段要特别注意。
port
port: 7880 是 LiveKit API 和 WebSocket 的主端口。生产环境一般不要直接暴露给公网,而是放在能终止 TLS 的负载均衡器或反向代理后面。
客户端连接的是:
wss://livekit.example.com
不是裸的 ws://ip:7880。
redis
配置 Redis 后,LiveKit 会自动进入分布式模式。Redis 用来保存房间数据、节点状态和消息总线。即使你现在只有一个节点,生产环境也建议接 Redis,后续扩容会少很多迁移成本。
Redis 如果启用密码、TLS、Sentinel 或 Cluster,需要按官方 config-sample.yaml 的对应字段配置。
keys
这里配置 API key 和 secret:
keys:
prod_key_xxx: prod_secret_xxx
你的后端签发 access token 时需要用这组 key/secret。不要把 secret 放进前端。
rtc.use_external_ip
云服务器常见情况是:进程看到的是内网 IP,但客户端必须连接公网 IP。use_external_ip: true 会让 LiveKit 尝试通过 STUN 发现公网 IP,并把它作为 ICE candidate 告诉客户端。
如果你在复杂 NAT、双网卡或内网部署里遇到连接问题,要重点检查这里。
UDP 端口范围
默认推荐是:
rtc:
port_range_start: 50000
port_range_end: 60000
每个参与者通常会消耗端口资源。端口范围太小,房间人数或并发房间上去后会出问题。
LiveKit 也支持 UDP mux,把 UDP 媒体流量收敛到单个端口:
rtc:
udp_port: 7882
设置 rtc.udp_port 后,port_range_start 和 port_range_end 就不再使用。这个方案对防火墙友好,但是否适合你的规模和网络,要实际压测。
TURN 怎么配
TURN 是自部署 LiveKit 里最值得认真配置的部分。理想情况下,WebRTC 直接用 UDP 连接 SFU,延迟低、质量好。但现实里很多用户在公司网络、学校网络、VPN、酒店 Wi-Fi 或移动运营商 NAT 后面,直接 UDP 可能失败。
LiveKit 内置 TURN Server,并且和 LiveKit 的认证集成。只有已经建立信令连接的客户端才能使用 TURN。
TURN/TLS
TURN/TLS 对很多防火墙最友好,因为看起来像普通 HTTPS 流量。
示例:
turn:
enabled: true
tls_port: 5349
domain: turn.example.com
cert_file: /path/to/turn.crt
key_file: /path/to/turn.key
如果没有四层负载均衡器,turn.tls_port 通常需要设成 443,因为这是会被广告给客户端的端口。
如果你用官方 VM + Caddy 生成器,证书和 443 入口会帮你处理很多细节。
TURN/UDP
如果网络允许 UDP,TURN/UDP 的延迟通常比 TURN/TCP/TLS 更好:
turn:
enabled: true
udp_port: 443
有些网络允许 UDP 443,因为 QUIC/HTTP3 越来越常见。这个配置可以提高连通率。
TURN 的常见坑
- TURN 域名和证书不匹配
- 证书文件路径在容器里不存在
- 云安全组只开了 TCP 443,没开 UDP
turn.tls_port配了 5349,但客户端实际只能访问 443- 多节点部署时,TURN/TLS 前面没有合适的四层负载均衡器
Kubernetes 部署
Kubernetes 部署适合已经有基础设施团队的场景。官方 Helm repo:
helm repo add livekit https://helm.livekit.io
helm repo update
安装:
helm install livekit livekit/livekit-server \
--namespace livekit \
--create-namespace \
--values values.yaml
升级:
helm repo update
helm upgrade livekit livekit/livekit-server \
--namespace livekit \
--values values.yaml
配置变更后要注意:如果只是 ConfigMap 变了,Kubernetes 不一定会自动重启 Pod。必要时手动触发 rollout restart。
kubectl rollout restart deployment/livekit -n livekit
Kubernetes 的几个现实限制
第一,LiveKit 需要 host networking。媒体端口要直接打到节点上。
第二,通常一个节点只跑一个 LiveKit Pod。因为端口是固定映射到宿主机的。
第三,升级时要考虑房间里的用户。LiveKit 支持 drain,官方 Helm chart 的 terminationGracePeriodSeconds 默认设得很长,用来让旧 Pod 慢慢退出,而不是直接踢掉正在通话的人。
第四,TLS 终止一般交给 Ingress 或云负载均衡器,TURN/TLS 证书可能还要单独以 Kubernetes Secret 形式导入:
kubectl create secret tls livekit-turn-tls \
--cert turn.crt \
--key turn.key \
--namespace livekit
Kubernetes 前置依赖
通常需要:
- Redis
- 主域名证书
- TURN/TLS 证书
- Helm
- 云厂商负载均衡器或 Ingress Controller
- 正确的防火墙和安全组
AWS 上常见选择是 ALB Ingress Controller。DigitalOcean 上官方文档提到 Nginx Ingress Controller 和 cert-manager。
Egress:录制和推流
LiveKit Cloud 默认提供 Egress。自部署时,Egress 是单独服务,需要额外部署。
Egress 可以做:
- 房间合成录制
- 单轨录制
- 输出 MP4 或 HLS
- 推流到 YouTube Live、Twitch、Facebook 等 RTMP 平台
Egress worker 会自动负载均衡任务。官方建议每个 Egress 实例至少给:
4 CPU / 4 GB RAM
Egress 配置示例:
api_key: your-api-key
api_secret: your-api-secret
ws_url: wss://livekit.example.com
redis:
address: redis.example.internal:6379
s3:
access_key: xxx
secret: xxx
region: ap-east-1
bucket: livekit-recordings
Docker 运行时有一个容易踩的点:从 Egress v1.7.6 起,Chrome sandbox 默认启用。Room Composite 和 Web Egress 依赖 Chrome,如果 Docker 没加权限,可能报 chrome failed to start。
官方 Docker 示例需要:
docker run --rm \
--cap-add SYS_ADMIN \
-e EGRESS_CONFIG_FILE=/out/config.yaml \
-v ~/livekit-egress:/out \
livekit/egress
Kubernetes 里可以用 Helm:
helm install livekit-egress livekit/egress \
--namespace livekit \
--values egress-values.yaml
如果你要同时录制多个房间,记得增加副本数或配置 autoscaling。一个实例不是无限吞任务。
Ingress:接入 RTMP / WHIP
Ingress 用来把外部媒体源送进 LiveKit 房间,比如 OBS 推 RTMP,或用 WHIP 接入 WebRTC 流。
自部署时,Ingress 也是单独服务。
官方建议每个 Ingress 实例至少:
4 CPU / 4 GB RAM
Ingress 服务配置示例:
api_key: your-api-key
api_secret: your-api-secret
ws_url: wss://livekit.example.com
redis:
address: redis.example.internal:6379
rtmp_port: 1935
whip_port: 8080
rtc_config:
udp_port: 7885
use_external_ip: true
LiveKit Server 还需要知道 Ingress 的公开地址,这样 CreateIngress API 才能返回正确的推流地址:
ingress:
rtmp_base_url: 'rtmps://ingress.example.com/live'
whip_base_url: 'https://ingress.example.com/whip'
如果多个 Ingress worker 并行,需要在前面放 TCP 负载均衡器。WHIP 可以走 HTTP 反向代理,RTMP 更适合 TCP LB。
SIP:电话接入
LiveKit SIP Server 可以让电话呼入 LiveKit 房间,也可以从 LiveKit 发起外呼。自部署时需要单独部署 SIP 服务。
最简单的 Docker Compose:
wget https://raw.githubusercontent.com/livekit/sip/main/docker-compose.yaml
docker compose up
本地配置示例:
api_key: your-api-key
api_secret: your-api-secret
ws_url: ws://localhost:7880
redis:
address: localhost:6379
sip_port: 5060
rtp_port: 10000-20000
use_external_ip: true
logging:
level: debug
SIP 的端口必须从公网可达,尤其是:
5060:SIP signaling10000-20000/UDP:RTP 媒体
如果电话能呼入但没有声音,优先查 RTP 端口、SDP 里的公网 IP,以及 SIP provider 侧的 ACL。
监控和排障
Prometheus
LiveKit Server 可以开启 Prometheus 指标:
prometheus_port: 6789
然后抓:
http://livekit-node:6789/metrics
Egress 和 Ingress 也支持 Prometheus 端口,可用于 autoscaling。
健康检查
API / WebSocket 入口要有负载均衡健康检查。Ingress/Egress 也有自己的 health endpoint。Kubernetes 里建议配置 readiness/liveness probe,不要只看容器进程是否存在。
日志级别
生产用 info。排障时临时改成 debug,排完恢复。WebRTC 日志非常容易刷屏。
log_level: info
Ingress 里是:
logging:
level: info
验证部署是否成功
1. 检查 API 和 WebSocket 域名
curl -I https://livekit.example.com
TLS 证书必须正常,不能有浏览器不信任的问题。
2. 用 LiveKit CLI 连接
安装 CLI 后,可以添加自部署项目:
lk cloud auth
如果你不用 Cloud 登录,而是本地自部署项目,按 CLI 提示添加 server URL、API key 和 secret。实际命令会随 CLI 版本变化,建议以 lk --help 为准。
3. 生成 token,跑一个前端 demo
你的后端要用 API key/secret 签发 token。前端只拿 token 和 wss://livekit.example.com。
不要把 API secret 放进浏览器代码。
4. 测 UDP 连通性
在真实网络里测试:
- 家庭宽带
- 公司网络
- 手机 4G/5G
- VPN 后面
- 海外用户网络
WebRTC “我本地可以”没有太大意义。TURN 和 UDP 的问题只有跨网络测试才会暴露。
升级策略
单机 VM 官方脚本默认会生成 /opt/livekit/docker-compose.yaml。升级时可以改 LiveKit 镜像:
image: livekit/livekit-server:v1.13.1
然后:
docker pull livekit/livekit-server:v1.13.1
systemctl restart livekit-docker
如果你想总是跑最新版,可以用:
image: livekit/livekit-server:latest
但生产环境我不建议这样做。固定版本、先 staging、再生产,排障会轻松很多。
Kubernetes 用 Helm upgrade。升级前看 release notes,尤其是 LiveKit Server、Egress、Ingress、SIP 的版本是否匹配。
本文整理时,GitHub 最新 release 显示:
- LiveKit Server:
v1.13.1 - Egress:
v1.13.0 - Ingress:
v1.5.0
实际部署前请重新检查 GitHub Release。
常见问题
用户能进房间,但没有音视频
优先查:
50000-60000/UDP是否开放- 云安全组是否只开了 TCP,没开 UDP
rtc.use_external_ip是否正确- ICE candidate 里是否出现内网 IP
- TURN 是否配置并可访问
公司网络里连不上
配置 TURN/TLS,并尽量让它走 443:
turn:
enabled: true
domain: turn.example.com
tls_port: 443
如果 UDP 443 可用,也可以加 TURN/UDP。
多节点房间会不会跨节点
LiveKit 的单个 room 会落在一个节点上。Redis 让集群节点能发现彼此、做路由和负载选择,但一个房间本身仍然要能被单节点承载。所以大房间容量取决于单节点 CPU 和带宽。
Kubernetes 可以随便扩 Pod 吗
不能像普通 HTTP 服务那样随便扩。LiveKit Pod 需要 host networking 和固定媒体端口。通常一个节点一个 Pod,并且节点防火墙要开放对应端口。
自部署支持 Egress、Ingress、SIP 吗
支持,但它们都是独立服务,不是 LiveKit Server 启动后自动就有。需要分别部署、配置 Redis、API key/secret、LiveKit ws_url,并开放各自端口。
一份可执行的上线清单
上线前至少检查这些项:
- 域名解析正确:
livekit.example.com、turn.example.com - TLS 证书可信且未过期
- LiveKit API 入口走 HTTPS/WSS
- Redis 已配置,且 LiveKit 能连接
- API key/secret 只在后端和服务端保存
- UDP 媒体端口已开放
- TURN/TLS 已配置并从公网可访问
- 手机网络、公司网络、VPN 网络都测试过
- Prometheus 指标已接入
- 日志能集中查看
- 升级流程已经在 staging 跑过
- Egress/Ingress/SIP 如需使用,已经单独压测
总结
LiveKit 自部署真正的门槛不是把容器跑起来,而是把 WebRTC 网络环境处理好。单机 VM 方案适合快速上线,官方生成器能省掉大量 Caddy、Docker Compose 和证书配置。Kubernetes 方案适合已有基础设施团队的场景,但要接受 host networking、节点端口和灰度升级带来的复杂度。
如果你只记住三件事:
- 生产环境要用可信 TLS 和
wss://。 - UDP 和 TURN 配置决定真实用户的连通率。
- Redis、监控、固定版本和升级流程,是从“能跑”到“能维护”的分界线。
把这三件事做好,LiveKit 自部署就不是玄学。剩下的才是容量规划、录制、接入外部流、SIP 电话和 AI Agent 这些更上层的问题。
参考资料
- LiveKit Self-hosting overview:
https://docs.livekit.io/home/self-hosting/ - LiveKit Deployment:
https://docs.livekit.io/home/self-hosting/deployment/ - LiveKit VM deployment:
https://docs.livekit.io/home/self-hosting/vm/ - LiveKit Kubernetes:
https://docs.livekit.io/home/self-hosting/kubernetes/ - LiveKit Firewall configuration:
https://docs.livekit.io/home/self-hosting/ports-firewall/ - LiveKit Egress self-hosting:
https://docs.livekit.io/home/self-hosting/egress/ - LiveKit Ingress self-hosting:
https://docs.livekit.io/home/self-hosting/ingress/ - LiveKit SIP self-hosting:
https://docs.livekit.io/home/self-hosting/sip/ - LiveKit server config sample:
https://github.com/livekit/livekit/blob/master/config-sample.yaml

Comments NOTHING