开源会议系统 VoceSpace 搭建分享:低成本替代腾讯会议
不少朋友在使用腾讯会议等主流通话软件时,都遇到过收费或免费版对参会人数/时长的限制。为解决这一痛点,我找到了开源解决方案 VoceSpace,并已成功搭建投入生产使用。(注意:需公网环境,否则无实际意义)
我的搭建配置:服务器:
H88K(同类硬件:ROCK 5B、Orange Pi 5),8核 CPU,16GB 内存,约 1200 元;
也可用 Intel 小主机(N100、N305)或各类 NAS,成本约 2000 元以内。
网络:
中国电信 1000M 家用宽带,理论上行 50Mbps(实际约 6MB/s),具备公网 IP。
操作系统:
Armbian 25.8.2 noble(基于 Ubuntu 24.04 LTS)
Docker / Compose:
Docker build 28.2.2,docker-compose v2.16.0
反向代理:
使用 1Panel 进行管理
一、功能简介
VoceSpace 是一款专为现代企业设计的安全通信平台。它基于 LiveKit 构建,利用 LiveKit 的强大性能和灵活性,为企业提供了一个稳定、高效的通信环境。VoceSpace 不仅支持视频和音频会议,还具备一系列高级功能,如设备设置、屏幕分享、多用户鼠标同屏、虚拟形象等,能够满足企业在多种场景下的通信需求。
腾讯会议的比较

自由部署
VoceSpace 的部署十分简单,我们提供了 Docker 镜像一键部署。对于个人使用而言,仅需计算服务器成本,配置较差的服务器也可丝滑使用。
相关地址
VoceSpace 官方网址:https://.vocespace.com/
VoceSpace 官方文档:https://doc.vocespace.com/
VoceSpace 作者微信:Privoce
二、部署过程
2.1先部署VoceChat获取安装的sh【可以省略此步,直接下一步】
2.1.1 部署VoceChat
# 运行容器
docker run -d --restart=always
-p 3009:3000
--name vocechat-server
privoce/vocechat-server:latest
2.1.2 VoceChat后台设置中,获取NAS安装的sh


提醒:
图片中 your.server.name 需要换成自已准备用的公网域名,端口如果非443 需要增加自定义的公网端口
保存修改后,会下载deploy_vocespace.sh (备用)
2.2直接编写安装脚本
如果不想按第1步安装VoceChat获取NAS安装的sh,可以直接新建deploy_vocespace.sh
2.2.1 设置服务安装位置
sudo -i
mkdir -p /root/data/docker_data/vocespace
cd /root/data/docker_data/vocespace
vim deploy_vocespace.sh
英文输入法下,按 i
deploy_vocespace.sh 内容如下(修改后复制粘贴)
#!/bin/bash
set -e # 任何命令失败立即退出,防止后续错误累积
# --- 自动生成的VoceSpace部署脚本 (服务器类型: nas) ---
DOMAIN="your.server.name" # 需要换成自己的公网域名
PASSWORD="vocespace" # 密码可自行修改
LICENSE="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6ImhhbkBwcml2b2NlLmNvbSIsImV4cGlyZXNfYXQiOjE3NzkyNzg0MDAsImNyZWF0ZWRfYXQiOjE3NDc3NDI0MDAsImRvbWFpbnMiOiIqIiwibGltaXQiOiJwcm8iLCJpZCI6IjZkZjgyMTMyLTIyODQtNGY2MS1iYmZhLWZkZmU4YmMzMWE2NyJ9.PiagYRDWSpzhIdbnY-pp8QeOf5Ij7neV8RMEafDgVT4"
# 许可证字符串,用于启用VoceSpace高级功能(如无限时长)
echo "Starting VoceSpace non-interactive deploy..."
echo "Server Type: nas"
# --- 检测宿主机的内网IP(用于后续配置)---
if command -v ip >/dev/null 2>&1; then
HOST_IP=$(ip route get 8.8.8.8 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}' | head -n1)
# 解析ip route get 8.8.8.8输出,提取“src”后面的IP地址
elif command -v ifconfig >/dev/null 2>&1; then
HOST_IP=$(ifconfig | grep "inet " | grep -v 127.0.0.1 | head -n1 | awk '{print $2}')
# 如果没有ip命令,用ifconfig获取第一个非127.0.0.1的内网IP
else
HOST_IP="127.0.0.1" # 降级为本地回环
fi
echo "Detected host IP: $HOST_IP"
# --- 检查Docker CLI是否存在 ---
if ! command -v docker >/dev/null 2>&1; then
if [ -e /var/run/docker.sock ]; then
echo "Found /var/run/docker.sock but no docker CLI. Run this script with an image that contains docker CLI, or use docker:24-cli and mount the socket."
# 如果Docker socket存在但无docker命令,提示用正确方式运行脚本
else
echo "Docker CLI not found. Please install Docker on the host before running this script."
exit 1
fi
fi
# --- 生成 LiveKit 密钥对 ---
echo "Generating LiveKit keys..."
docker run --rm -v "$(pwd)":/output livekit/generate --local || echo "livekit/generate failed, falling back to devkey/secret"
# 尝试用 livekit/generate 镜像生成随机密钥(输出到当前目录的livekit.yaml),失败则使用硬编码的 devkey/secret
KEY="devkey"
SECRET="secret"
if [ -f ./livekit.yaml ]; then
# 如果 livekit.yaml 存在,从中提取第一组 key/secret
KEY_LINE=$(awk '/^keys:/{flag=1;next} flag && /^[[:space:]]*[^:]+:/' livekit.yaml | head -n1)
if [ -n "$KEY_LINE" ]; then
KEY=$(echo "$KEY_LINE" | sed 's/^[[:space:]]*//;s/"//g' | awk -F: '{print $1}')
SECRET=$(echo "$KEY_LINE" | sed 's/^[[:space:]]*//;s/"//g' | awk -F: '{print $2}' | sed 's/^ *//')
fi
fi
echo "LiveKit key: $KEY"
# --- 写入 LiveKit 标准配置文件 ---
cat > livekit_std.yaml <<-YAML
port: 7880
bind_addresses:
- 0.0.0.0
rtc:
tcp_port: 7881
port_range_start: 50000
port_range_end: 60000
use_external_ip: true
enable_loopback_candidate: false
turn:
enabled: false
keys:
$KEY: $SECRET
logging:
json: false
level: info
YAML
# 注意:生产环境中建议启用 TURN,此处仅为简单部署关闭
echo "Written livekit_std.yaml"
# --- 写入 VoceSpace 配置文件 ---
cat > vocespace.conf.json <<-JSON
{
"livekit": {
"key": "$KEY",
"secret": "$SECRET",
"url": "wss://your.server.name:端口" # 必须替换为实际公网域名和端口(除443外,需要增加自定义)
},
"codec": "vp9",
"resolution": "1080p",
"maxBitrate": 3000000,
"maxFramerate": 30,
"priority": "medium",
"redis": {
"enabled": true,
"host": "redis", # 建议改成容器名(如"redis")或者主机ip或者是容器ip
"port": 6379,
"password": "vocespace", # redis的密码
"db": 0
},
"serverUrl": "your.server.name", # 管理后台地址,也需要替换为域名:端口
"hostToken": "vocespace", # 管理后台的密码,建议修改
"license": "$LICENSE"
}
JSON
echo "Wrote vocespace.conf.json"
# --- 根据CPU架构选择VoceSpace镜像 ---
ARCH=$(uname -m)
if [ "$ARCH" = "x86_64" ] || [ "$ARCH" = "amd64" ]; then
IMG="privoce/vocespace:latest"
elif [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
IMG="privoce/vocespace:latest_arm"
else
IMG="privoce/vocespace:latest" # 未知架构也尝试x86(可能失败)
fi
echo "Pulling $IMG"
docker pull "$IMG"
echo "Deploy script finished. Access Voce Chat at http://$DOMAIN:3008 or http://$HOST_IP:3008"
按一下 esc,然后 :wq 保存退出。
提醒:
将 deploy_vocespace.sh 中的 your.server.name 替换为你的公网域名(或 IP)。
确保服务器内部开放了以下端口:
3008(VoceSpace Web 管理界面)
7880(LiveKit WebSocket)
7881(LiveKit TCP)
50000~60000(LiveKit UDP 媒体流)
如果使用防火墙,请放行这些端口。
反代3008和7880 到公网端口(后面有介绍)
访问 https://你的域名:端口 进行管理员初始化,密码为 vocespace(可在配置中修改)。
2.3 运行安装脚本,生成配置文件
2.3.1 给deploy_vocespace.sh 权限并运行
chmod 666 ./deploy_vocespace.sh
sh deploy_vocespace.sh
2.3.2 执行deploy_vocespace.sh
2.3.2.1执行sh后会生成,三个配置文件
分别是(livekit_std.yaml、livekit.yaml、vocespace.conf.json)
其中 livekit_std.yaml和livekit.yaml 不需要修改,这两个文件关键生成了“keys”
vocespace.conf.json 是关键配置文件
{
"livekit": {
"key": "$KEY",
"secret": "$SECRET",
"url": "wss://your.server.name:端口" # 必须替换为实际公网域名和端口(除443外,需要增加自定义)
},
"codec": "vp9",
"resolution": "1080p",
"maxBitrate": 3000000,
"maxFramerate": 30,
"priority": "medium",
"redis": {
"enabled": true,
"host": "redis", # 建议改成容器名(如"redis")或者主机ip或者是容器ip
"port": 6379,
"password": "vocespace", # redis的密码
"db": 0
},
"serverUrl": "your.server.name", # 管理后台地址,也需要替换为域名:端口
"hostToken": "vocespace", # 管理后台的密码,建议修改
"license": "$LICENSE"
}
上述json 中的注释必须要删除掉
2.4 新建docker-compose文件
2.4.1 新建chat_net网络
docker network create chat_net
2.4.2 新建compose文件
sudo -i
cd /root/data/docker_data/vocespace
vim docker-compose.yml
英文输入法下,按 i
docker-compose如下:(复制或粘贴)
services:
livekit:
image: livekit/livekit-server
container_name: livekit-server
volumes:
- ./livekit_std.yaml:/etc/livekit.yaml
command: --config /etc/livekit.yaml
restart: unless-stopped
network_mode: host # 网络必须是host模式
redis:
image: redis:latest
container_name: vocespace_redis
ports:
- "6379:6379"
command: redis-server --requirepass vocespace --protected-mode no # 以密码 vocespace 启动 Redis
restart: unless-stopped
networks: #网络设置
- chat_net
vocespace:
image: privoce/vocespace:latest_arm # ARM 架构镜像标签 如果x86 删除 "_arm"
container_name: vocespace
ports:
- "3008:3000"
volumes:
- ./vocespace.conf.json:/app/vocespace.conf.json
depends_on:
- livekit
- redis
restart: unless-stopped
networks: #网络设置
- chat_net
networks:
chat_net:
external: true
按一下 esc,然后 :wq 保存退出。
2.5 运行容器
查看端口是否被占用(以 3008 为例),输入:
lsof -i:3008 #查看 3008 端口是否被占用,如果被占用,重新自定义一个端口
如果啥也没出现,表示端口未被占用,我们可以继续下面的操作了~
如果出现:
lsof: command not found
运行:
apt install lsof #安装 lsof
如果端口没有被占用(被占用了就修改一下端口,比如改成 3018,注意 docker 命令行里和防火墙都要改)
最后:
cd /root/data/docker_data/vocespace # 来到 docker-compose 文件所在的文件夹下
docker-compose up -d # 启动容器
理论上我们就可以输入 http://ip:3008 访问了。【此时还不能使用】
2.6 反向代理
我是以1panel为列,如图

官方Nginx 配置示列
# HTTPS 反向代理配置
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name your.server.name; # modify ⚠️
ssl_certificate /etc/letsencrypt/live/your.server.name/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your.server.name/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# 应用主服务(例如前端或后端 Web 接口)
location / {
proxy_pass http://主机ip:3008; # 可以改为容器名http://容器名:3000
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
# WebRTC 服务代理(端口和路径视项目而定)
location /rtc {
proxy_pass http://主机ip:7880;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
二、应用配置
路由器防火墙端口放行反向代理的端口
理论上我们就可以输入 https://your.server.name 访问了【如果不是443 需要加端口】

点击“加入”

进入会议界面

更多->成员,可以获取邀请链接
更多->管理,可以有更多设置
后台管理地址,https://your.server.name/dashboard

限制权限,仅指定人可以创建房间

三、目前遇到的问题
待优化的内容:【已反馈作者】
1.配置稍有点不直观,能不能docker-compose 拉起来,然后访问web配置
2.虽然可以指定用户(白名单)开房间,但个人建议还要增加“入会人员凭临时密码入会”否则只要知道房间,就能参会,太不安全了【截址发文前,有bug,建议别指定】
3.设了白名单保存后,vocespace.conf.json 排版,就变了,看了很难受
四、结尾
祝大家用得开心,有问题可以去 GitHub 提 Issues,也可以在评论区互相交流探讨。
同时,项目处于刚开始阶段,有能力给项目做贡献的同学,也欢迎积极加入到 项目 中来,贡献自己的一份力量!
参考资料
VoceSpace 官方网址:https://.vocespace.com/
VoceSpace 官方文档:https://doc.vocespace.com/
VoceSpace 作者微信:Privoce
作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~
