部署教程
从空白主机到可用 Lag 实例的分步操作指南。每一步都附带可直接执行的检查命令。提供商注册见 Prism、OIDC 与 OAuth;备份、升级与故障排查见运维。
第 1 步:准备工作
- 一台安装 Docker Engine 与 Compose 插件的 Linux 主机。
- 一个身份提供商注册(Prism、OIDC 或 OAuth 2.0),或明确决定启用昵称访客。
- 客户端可达的端口:TCP
7880-7881与 UDP50000-50200;3000是 Web 入口。 - 可用于
EXTERNAL_IP的公网地址;暴露到互联网前还需域名与 TLS 证书。
第 2 步:获取文件
git clone https://github.com/wyf9/lag-server.git
cd lag-server
cp .env.example .env.env.example 是不安全的本机示例,其中每个值都应视为占位符。
第 3 步:编辑 .env
至少设置以下内容:
| 变量 | 应填写的内容 |
|---|---|
ALLOWED_HOSTS | 浏览器访问的精确 origin,例如 https://lag.example.com,不含 path 和末尾斜线 |
AUTH_PROVIDER | prism、oidc 或 oauth2,以及对应提供商的变量 |
AUTH_CLIENT_ID / AUTH_CLIENT_SECRET | 提供商注册处发放的凭据 |
GUEST_ENABLED | 除非确需昵称访客,否则为 false |
LAG_VOICE_KEY / LAG_VOICE_SECRET | 新的随机值,每项可用 openssl rand -hex 32 生成 |
EXTERNAL_IP | 客户端可访问的地址 |
VOICE_URL | 客户端将使用的信令 URL,必须可被浏览器访问 |
LAG_BIND_ADDRESS | 默认 127.0.0.1;客户端直连本机时改为 0.0.0.0 |
# 启动前的示例检查
grep -E '^(ALLOWED_HOSTS|AUTH_PROVIDER|EXTERNAL_IP|VOICE_URL|LAG_BIND_ADDRESS)=' .env第 4 步:启动
compose.yml 默认拉取 ghcr.io/wyf9/lag-server:latest。不便随时重建的环境应固定版本标签或摘要:
docker compose up -d
docker compose ps
curl --fail http://localhost:3000/api/health/api/health 只报告应用进程健康,不代表 PostgreSQL 或 LiveKit 完全就绪。PostgreSQL 数据位于命名卷 lag_data,请放在持久化存储上。
第 5 步:验证安装
- 在浏览器打开第 3 步配置的 origin,通过提供商登录(或在启用时以访客身份进入)。
- 确认第一个外部身份获得了启动用
platform_admingrant,并对其审核(见权限)。 - 创建房间、发送消息,刷新页面后重新连接,确认会话持久。
继续之前,请在服务器局域网以外的网络完成这些验证。
第 6 步:开放语音端口
| 端口 | 协议 | 暴露方式 | 用途 |
|---|---|---|---|
3000 | TCP | 公开或位于 HTTPS 代理后 | Web UI、REST API、/api/ws |
3001 | TCP | 仅内部 | Fastify API |
3002 | TCP | 仅内部 | SvelteKit 服务 |
5432 | TCP | 仅内部 | 内置 PostgreSQL |
7880 | TCP | 客户端可达 | LiveKit 信令/API |
7881 | TCP | 客户端可达 | LiveKit RTC TCP 回退 |
50000-50200 | UDP | 客户端可达 | LiveKit RTC 媒体 |
把 TCP 7880-7881 和完整 UDP 范围 50000-50200 转发到容器宿主机,并保持 3001、3002、5432 私有。ufw 示例:
sudo ufw allow 7880/tcp
sudo ufw allow 7881/tcp
sudo ufw allow 50000:50200/udp不要只映射 HTTP:UDP 被阻止时,信令可能成功但没有声音。运营商级 NAT 或严格企业网络可能需要 TURN 方案;本仓库没有内置或声称已实现 TURN。
检查:局域网以外的客户端能加入语音房间并正常通话。
第 7 步:配置 HTTPS
在端口 3000 前终止 HTTPS,包括 /api/ws 的 WebSocket upgrade,并为 WebSocket 设置足够长的空闲超时。nginx server 块示例:
server {
listen 443 ssl;
server_name lag.example.com;
# ssl_certificate /path/to/fullchain.pem;
# ssl_certificate_key /path/to/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}随后:
- 仅当边缘按上例覆写该头时才设置
PROXY_HEADER=x-forwarded-for,否则保持未设置。 - 把
ALLOWED_HOSTS更新为 HTTPS origin 并重启:docker compose up -d。 - 不要将
3001作为第二条公网 API 路径暴露。 - 语音信令 URL 也必须可经 TLS 访问:站点使用 HTTPS 时,浏览器会阻止不安全的
ws://混合内容,因此VOICE_URL必须是客户端可达的wss://URL。内置默认值偏向开发环境,本仓库不附带该代理配置。
检查:curl --fail https://lag.example.com/api/health 成功、登录可用,且局域网以外的浏览器控制台没有混合内容错误。
第 8 步(可选):从本地源码构建
若要从已检出的源码构建而非拉取已发布镜像,请将 compose-build.override.yml 重命名为 compose.override.yml,Docker Compose 会自动合并:
mv compose-build.override.yml compose.override.yml
docker compose up -d --build删除 compose.override.yml 即可恢复使用已发布镜像。
对外开放前
- 替换
.env中的全部开发值;仓库中的 Compose 文件不是完整生产配置。 - 精确注册回调
https://your-origin/api/auth/callback,暴露实例前先阅读认证。 - 从站外浏览器验证准确的公共 URL、证书、信令路径与媒体端口。
- 按运维记录备份与升级方案。
扩展限制
不要让多个一体化副本使用复制的数据卷。WebSocket presence 位于内存,PostgreSQL 是内置的,LiveKit 节点路由也未协调。高可用或水平扩展需要架构变更和针对性部署测试。