中控服务部署

⚠️ 观看提示:哔哩哔哩默认 360P 清晰度,建议手动切换至 720P 或高清画质

概述

中控服务说明

中控服务镜像集成了以下核心模块:

  • 中控-投屏控制服务
    负责群控投屏的操作执行、命令下发及设备交互,是系统的核心控制通道。
  • 设备-脚本通信服务
    支持多设备在执行云控脚本时进行实时通信,常用于多设备协同任务。
  • 设备-代码通信服务
    用于设备间执行云控代码时的指令交互,提升多设备协同的实时性与一致性。

通信机制

系统默认 优先使用 P2P 通信模式 进行数据交换。

P2P 通道未建立成功时,系统将自动切换至 中控-投屏控制服务,确保所有控制操作可以正常进行。

私有部署优势

私有部署可以带来以下优势:

  • 更快的响应速度
  • 更稳定的控制能力
  • 更流畅的操作体验
当绑定设备数量超过 10 台时,建议使用私有部署模式,以确保系统性能与稳定性。

部署教程

本教程介绍如何在 CentOS 8 及 Ubuntu 24 系统上安装 Docker,并部署中控服务。

准备阶段

购买云服务器

中控服务对服务器配置要求极低,本文档示例使用低配服务器即可稳定运行,无需高性能配置。

推荐云厂商:

  • 阿里云
  • 腾讯云
  • 华为云
  • 百度云
  • AWS

参考服务器配置:

  • CPU:2核(够用,1核也可)
  • 内存:2G(够用,1G也可)
  • 带宽:3Mbps
  • 系统:CentOS 8
本教程命令基于 CentOS 8 / Ubuntu 24 演示,其他 Linux 发行版(如 Debian)同样适用,部分命令可能需要根据包管理器调整。

¥99 / 年 即可使用,该配置可支撑 100~500 台设备控制

购买步骤:

  1. 打开阿里云官网:https://www.aliyun.com
  2. 推荐服务器区域:华东、华北、香港、北京,选择离用户最近区域,延迟更低
  3. 操作系统选择:CentOS 8 64位
  4. 设置 root 密码 并开通实例。

下载服务器连接工具(Windows)

推荐工具:Xshell 6 、 Xftp 6 安装教程:https://blog.csdn.net/weixin_57558097/article/details/127416711

连接服务器

使用 Xshell 连接服务器

  1. 打开 Xshell
  2. 新建会话
  3. 填写服务器信息
    • 主机:阿里云公网IP
    • 协议:SSH
    • 端口:22
    • 用户名:root
    • 密码:服务器密码

使用 Xftp 上传文件

打开 Xftp

连接方式与 Xshell 相同,用于上传 Docker镜像文件


安装 Docker 环境

卸载旧版 Docker(如果有)

sudo yum remove -y docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine \
docker-ce

(可选)清空 Docker 数据

sudo rm -rf /var/lib/docker/*

安装依赖工具

sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2 --skip-broken

Ubuntu 系统需先添加 Docker 官方 GPG 密钥

# 创建 keyrings 目录
sudo mkdir -p /etc/apt/keyrings

# 下载并添加 Docker GPG 密钥
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 设置密钥文件权限(确保 apt 能读取)
sudo chmod a+r /etc/apt/keyrings/docker.gpg

配置阿里云 Docker 镜像源

sudo yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo


# 替换默认源
sudo sed -i 's|download.docker.com|mirrors.aliyun.com/docker-ce|g' /etc/yum.repos.d/docker-ce.repo

安装 Docker

sudo dnf makecache
sudo yum install -y docker-ce

启动 Docker

sudo systemctl start docker
sudo systemctl enable docker

配置 Docker 镜像加速器

sudo mkdir -p /etc/docker

创建配置:

sudo tee /etc/docker/daemon.json > /dev/null <<'EOF'
{
  "registry-mirrors": [
    "https://mirror.aliyuncs.com",
    "https://dockerproxy.com",
    "https://docker.m.daocloud.io",
    "https://docker.mirrors.ustc.edu.cn"
  ]
}
EOF

重启 Docker

sudo systemctl daemon-reload
sudo systemctl restart docker

验证 Docker

查看版本

docker -v

查看状态

systemctl status docker

Docker 测试

拉取 Redis 镜像

docker pull redis

查看镜像

docker images | grep redis

删除镜像

docker rmi redis

安装中控服务镜像

下载镜像:https://vip.123pan.cn/1823071502/公共/工具/device-controller-1.0.tar

上传至服务器/mnt目录下:/mnt/device-controller-1.0.tar

导入镜像

docker load -i /mnt/device-controller-1.0.tar

检查镜像

docker images

如果看到device-controller:1.0说明导入成功。

防火墙放行端口(以 CentOS/firewalld 为例)

需要放行TCP端口:235623572358

# 检查 firewalld 是否正在运行
sudo systemctl status firewalld

# 如果 firewalld 未运行,执行以下命令启动它
sudo systemctl start firewalld


sudo firewall-cmd --add-port=22/tcp --permanent
sudo firewall-cmd --add-port=2356/tcp --permanent
sudo firewall-cmd --add-port=2357/tcp --permanent
sudo firewall-cmd --add-port=2358/tcp --permanent

重载防火墙

sudo firewall-cmd --reload

查看端口

sudo firewall-cmd --list-ports

云服务器安全组放行(必做)

云服务器默认会通过安全组拦截外部端口访问,即使本地防火墙已放行,外部设备依然无法连接。

请在云服务商控制台(阿里云、腾讯云、华为云、AWS 等)添加安全组规则,放行以下 TCP 端口

  • 2356
  • 2357
  • 2358
说明:安全组是云服务器的外层防火墙,必须单独配置,不可省略。若你的服务器没有安全组,只需放行系统本地防火墙即可,此步骤可跳过。

运行中控服务

⚠️ 运行容器前,必须替换以下参数

参数名说明示例
user云控用户名ceshi3
pwd云控密码qwer1234
cipher卡密(联系客服免费领取)tIeSKh19vk

执行以下命令来创建并启动容器。此命令会使用本地已有的 device-controller:1.0 镜像,并将本地端口映射到容器内的服务端口。

docker run --name device-controller \
  -p 2356:2356 \
  -p 2357:2357 \
  -p 2358:2358 \
  -e user=ceshi3 \
  -e pwd=qwer1234 \
  -e cipher=tIeSKh19vk \
  device-controller:1.0
参数作用示例值
--name指定容器名称,方便管理device-controller
-p 宿主端口:容器端口端口映射,外部访问映射到容器内部服务2356:23562357:23572358:2358
-e 变量名=值设置环境变量,传递配置参数user=ceshi3pwd=qwer1234cipher=tIeSKh19vk
镜像名:标签指定要运行的镜像和版本device-controller:1.0

直接退出并停止容器的快捷键:Ctrl + C

  • 卡密用于防止滥用,免费提供
  • 采用 一机一码机制
  • 每位用户 限领一枚卡密
  • 卡密 长期有效

常见错误

常见错误 1:OCI 运行时错误

#错误信息
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: unable to retrieve OCI runtime error (open /run/containerd/io.containerd.runtime.v2.task/moby/48fe6d34675b407cd96af00362ed1051e53636d8b3a1b9f8d9b9a07d364df2fb/log.json: no such file or directory): runc did not terminate successfully: exit status 127: unknown.

#下面是检查和解决办法

# 查看runc是否存在
runc --version

# 查看docker版本
docker version

# 检查libseccomp是否存在
rpm -qa | grep libseccomp

# 安装libseccomp
sudo yum downgrade libseccomp-2.5.1-1.el8

# 更新libseccomp
sudo yum update libseccomp

# 再次查看docker版本(此时应显示runc版本)
docker version

# 重启docker服务
sudo systemctl restart docker

常见错误 2:端口映射失败

#错误信息
docker: Error response from daemon: driver failed programming external connectivity on endpoint device-controller (1e5552b5ea689a400c450a5d8dc211b9e67d1e392d14df1a1110271aa2e9bf1e):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 2358 -j DNAT --to-destination 172.17.0.2:2358 ! -i docker0: iptables: No chain/target/match by that name.

#原因 Docker容器做端口映射报错或者宿主机防火墙改动都可能造成

#解决方法
systemctl restart docker

设置开机自启

创建 systemd 服务:

cat <<EOF | sudo tee /etc/systemd/system/device-controller.service > /dev/null
[Unit]
Description=Device Controller Service
After=docker.service network.target

[Service]
ExecStart=/usr/bin/docker start -a device-controller
ExecStop=/usr/bin/docker stop device-controller
Restart=always
RestartSec=5s

[Install]
WantedBy=multi-user.target
EOF

启用服务:

# 重载 systemd
sudo systemctl daemon-reload

# 启用开机自启
sudo systemctl enable device-controller.service

# 查看服务是否已启用
sudo systemctl is-enabled device-controller.service

# 启动服务
sudo systemctl start device-controller.service

查看服务状态与日志:


# 查看状态
sudo systemctl status device-controller.service

# 查看日志
sudo journalctl -u device-controller.service -f

重启服务器

sudo reboot

检查服务状态

查看容器:

docker ps

预期输出(需能看到 device-controller 容器处于 Up 状态):

CONTAINER ID   IMAGE                  STATUS          PORTS
xxxxxxx        device-controller:1.0  Up X seconds    0.0.0.0:2356->2356/tcp, 0.0.0.0:2357->2357/tcp, 0.0.0.0:2358->2358/tcp

检查端口:

ss -tuln | grep 235

预期输出(需包含以下 3 个端口的监听记录,代表服务就绪):

LISTEN  0  128  0.0.0.0:2356  0.0.0.0:*  
LISTEN  0  128  0.0.0.0:2357  0.0.0.0:*  
LISTEN  0  128  0.0.0.0:2358  0.0.0.0:*  

云控后台切换服务地址

当后台服务器切换服务地址后,手机端 云控App 需手动断开后重新连接,或重启 APP 以生效。


可选:配置域名 + SSL 证书

本节为可选步骤。 上文基于 公网IP 的配置已经能正常工作,如果你的设备连接已满足需求,可以跳过此步骤。

补上域名 + 证书后,可获得以下能力:

能力用 IP(无证书)用域名 + 证书
换服务器 IP❌ 客户端全部要改只改 DNS 解析
浏览器兼容⚠️ 部分 HTTPS 页面会被拦完全兼容

总结:IP 版能用,域名 + 证书版更统一、更好维护

前置条件

  1. 已有一个备案域名(如 example.com
  2. 域名 DNS 解析可控
  3. 能从云服务商申请 SSL 证书

安装 Nginx(未安装时执行)

sudo yum install -y nginx
sudo systemctl start nginx
sudo systemctl enable nginx

验证

nginx -v
systemctl status nginx

能输出 nginx version: nginx/x.x.x 且状态为 active (running) 即可。

Nginx 配置目录

系统主配置证书目录
CentOS/etc/nginx/nginx.conf/etc/nginx/cert/
Ubuntu/etc/nginx/nginx.conf/etc/nginx/cert/

操作步骤

添加子域名解析

登录域名 DNS 控制台,添加一条 A 记录

字段
主机记录ws
记录类型A
记录值你的服务器公网 IP(如 191.191.191.191
TTL600

最终效果ws.example.com191.191.191.191

验证

nslookup ws.example.com 8.8.8.8

申请 SSL 证书

在云服务商(阿里云 / 腾讯云 / 百度云 等)的 SSL 证书 控制台:

  1. 申请免费证书(有效期一般 3 个月)
  2. 绑定域名:ws.example.com
  3. 等待签发

下载证书

在证书控制台点击下载,选择 PEM (Nginx, SLB) 格式。

下载后一般有 2 个文件:

文件内容
ws.example.com.crt服务器证书 + 中间证书(已拼接)
ws.example.com.key私钥

上传证书到服务器

# 新建目录(若不存在)
sudo mkdir -p /usr/local/nginx2/cert

# 上传证书(用 Xftp 或 scp 传到服务器,再拷到目标路径)
# 证书文件名保持原样,不要重命名
sudo cp ws.example.com.crt /usr/local/nginx2/cert/
sudo cp ws.example.com.key /usr/local/nginx2/cert/

设置权限

sudo chmod 600 /usr/local/nginx2/cert/ws.example.com.key
sudo chmod 644 /usr/local/nginx2/cert/ws.example.com.crt

放行 80 / 443 端口(必做)

服务器本机防火墙放行:

sudo firewall-cmd --add-port=80/tcp --permanent
sudo firewall-cmd --add-port=443/tcp --permanent
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports

云服务商安全组(必做,否则外网访问不了):

去云服务商控制台(阿里云 / 腾讯云 / 华为云 / AWS 等)→ 云服务器 → 安全组 → 入方向规则 → 添加:

协议端口源 IP说明
TCP800.0.0.0/0HTTP
TCP4430.0.0.0/0HTTPS / WSS
安全组是云服务器的外层防火墙,必须单独配置,不可省略。 只配置本机防火墙、不配置安全组,外网依然访问不到。

修改 Nginx 配置

编辑 nginx.conf,在 http 块里新增两个 server:

  # ========================================
  # 中控服务 - wss(端口 443)
  # ========================================
  server {
    listen 443 ssl http2;
    server_name ws.example.com;

    ssl_certificate cert/ws.example.com.crt;
    ssl_certificate_key cert/ws.example.com.key;
    ssl_session_cache shared:SSL:200m;
    ssl_session_timeout 1d;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # WebSocket 公共代理设置
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
    proxy_connect_timeout 10s;
    proxy_read_timeout 180s;
    proxy_send_timeout 180s;
    proxy_next_upstream off;
    proxy_socket_keepalive on;

    location /device/comm {
      proxy_pass http://127.0.0.1:2358;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
    location /device/scriptlog {
      proxy_pass http://127.0.0.1:2356;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
    location /device/codelog {
      proxy_pass http://127.0.0.1:2357;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }

    location = /health {
      access_log off;
      default_type text/plain;
      return 200 "healthy\n";
    }
  }

  # ========================================
  # 中控服务 - ws(端口 80)
  # ========================================
  server {
    listen 80;
    server_name ws.example.com;

    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
    proxy_connect_timeout 10s;
    proxy_read_timeout 180s;
    proxy_send_timeout 180s;
    proxy_next_upstream off;

    location /device/comm {
      proxy_pass http://127.0.0.1:2358;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
    location /device/scriptlog {
      proxy_pass http://127.0.0.1:2356;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
    location /device/codelog {
      proxy_pass http://127.0.0.1:2357;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }

    location = /health {
      access_log off;
      default_type text/plain;
      return 200 "healthy\n";
    }
  }

重载 Nginx

sudo /usr/sbin/nginx2 -t
sudo /usr/sbin/nginx2 -s reload

云控后台填写域名

登录云控后台,在「服务地址管理」页面把中控服务地址从 IP 改成域名:

服务原地址(IP)新地址(域名)
中控-投屏控制191.191.191.191ws.example.com
设备-脚本通信191.191.191.191ws.example.com
设备-代码通信191.191.191.191ws.example.com

保存配置后,重新登录云控后台生效。

手机端重连

在手机端云控 App 中断开当前连接后重新连接,或者重启 App,即可生效。


常用 Docker 管理命令

查看所有容器(包含运行和停止的)

docker ps -a
参数作用
-a显示所有容器(含停止状态)

查看正在运行的容器

docker ps
参数作用
只显示正在运行的容器

停止容器

docker stop device-controller
参数作用示例值
容器名/ID指定要停止的容器device-controller

启动已停止的容器

docker start device-controller
参数作用示例值
容器名/ID指定要启动的容器device-controller

删除容器 需先停止容器,再执行删除操作:

docker stop device-controller
docker rm device-controller
命令作用示例值
docker stop停止目标容器device-controller
docker rm删除已停止的容器device-controller

删除镜像(如需重建镜像)

docker rmi device-controller:1.0
参数作用示例值
镜像名:标签指定要删除的镜像device-controller:1.0

查看容器日志(实时输出)

docker logs -f device-controller
参数作用示例值
-f持续跟踪日志实时输出device-controller