- 前置准备:
- 端口防火墙开通:
sudo ufw allow 21114:21119/tcpsudo ufw allow 21116/udpsudo ufw reload- 如果云厂商,需要到平台开通
- 端口防火墙开通:
- 部署容器
官方部署
version: '3'
services:
hbbs:
image: rustdesk/rustdesk-server:latest
container_name: rustdesk-hbbs
command: hbbs -r 119.28.106.79:21117
ports:
- "21115:21115" # NAT类型测试
- "21116:21116" # ID服务器 (TCP)
- "21116:21116/udp" # ID服务器 (UDP)
- "21118:21118" # WebSocket
- "21119:21119" # 备用
volumes:
- ./hbbs:/root
restart: unless-stopped
hbbr:
image: rustdesk/rustdesk-server:latest
container_name: rustdesk-hbbr
command: hbbr
ports:
- "21117:21117" # 中继服务器
volumes:
- ./hbbr:/root
restart: unless-stopped镜像部署
- 多了一个 api 能力
- 需要通过
RUSTDESK_API_RUSTDESK_KEY和KEY指定密钥,否则会无法连接,这里的密钥可以手动生成 - 通过:
- http://服务器IP:21114 进入RustDesk 管理面板
- 修改用户名:
sqlite3 /data/rustdesk/api/rustdeskapi.db "UPDATE users SET username='新用户名' WHERE username='旧用户名';" - 修改密码:
docker exec rustdesk-server /app/apimain reset-admin-pwd 你的新密码 - 查看所有用户:
sqlite3 /data/rustdesk/api/rustdeskapi.db "SELECT username, is_admin FROM users;" - 密钥:
- 私钥:
/data/rustdesk/server/id_ed25519 - 公钥:
/data/rustdesk/server/id_ed25519.pub,客户端连接使用
- 私钥:
#!/bin/bash
set -e
echo "=== RustDesk 自动捕获与闭环部署脚本 (自动获取IP版) ==="
# --- 1. 自动获取服务器IP ---
echo "正在自动检测服务器 IP..."
# 尝试获取公网 IP(使用多个服务,防止单个服务失效)
SERVER_IP=$(curl -s --max-time 5 http://ipinfo.io/ip 2>/dev/null || \
curl -s --max-time 5 http://ifconfig.me 2>/dev/null || \
curl -s --max-time 5 http://api.ipify.org 2>/dev/null || \
echo "")
# 如果获取不到公网 IP,使用内网 IP
if [ -z "$SERVER_IP" ]; then
SERVER_IP=$(ip route get 1.1.1.1 2>/dev/null | grep -oP 'src \K\S+' || \
hostname -I 2>/dev/null | awk '{print $1}' || \
ip addr show eth0 2>/dev/null | grep -oP 'inet \K\d+\.\d+\.\d+\.\d+' | head -1 || \
echo "")
echo "⚠️ 无法获取公网 IP,使用内网 IP: $SERVER_IP"
else
echo "✅ 检测到公网 IP: $SERVER_IP"
fi
# 如果还是获取不到,报错退出
if [ -z "$SERVER_IP" ]; then
echo "❌ 错误:无法自动检测服务器 IP,请手动设置 SERVER_IP 变量"
exit 1
fi
# --- 2. 配置定义 ---
BASE_DIR="/data/rustdesk"
# 使用 hex 格式生成 JWT_KEY,避免 Base64 字符问题
JWT_KEY=$(openssl rand -hex 32)
mkdir -p "$BASE_DIR/server" "$BASE_DIR/api"
cd "$BASE_DIR"
# --- 3. 阶段一:触发 Key 生成 ---
echo ""
echo "阶段 1:启动临时容器以生成原装密钥..."
cat > compose.yml << EOF
services:
rustdesk:
container_name: rustdesk-server
image: lejianwen/rustdesk-server-s6:latest
environment:
- RELAY=${SERVER_IP}:21117
- TZ=Asia/Shanghai
volumes:
- ./server:/data
restart: "no"
EOF
docker compose up -d
# 轮询等待密钥生成,最多等待 120 秒
echo "等待镜像初始化并生成密钥文件..."
PUB_KEY_FILE="./server/id_ed25519.pub"
MAX_WAIT=120
WAITED=0
while [ ! -f "$PUB_KEY_FILE" ] && [ $WAITED -lt $MAX_WAIT ]; do
sleep 2
WAITED=$((WAITED + 2))
echo " 已等待 ${WAITED} 秒,密钥文件尚未生成..."
done
if [ -f "$PUB_KEY_FILE" ]; then
# 读取并去除所有可能的不可见字符
CAPTURED_KEY=$(cat "$PUB_KEY_FILE" | tr -d '\n\r ')
echo "✅ 成功捕获密钥: ${CAPTURED_KEY:0:20}..."
else
echo "❌ 错误:镜像未能在 ${MAX_WAIT} 秒内生成密钥文件!"
echo "检查容器日志:"
docker logs rustdesk-server 2>&1 | tail -20
exit 1
fi
# 停止临时容器
docker compose down
# --- 4. 阶段二:动态重写正式配置 ---
echo ""
echo "阶段 2:注入捕获的密钥并重新部署正式服务..."
cat > compose.yml << EOF
services:
rustdesk:
container_name: rustdesk-server
image: lejianwen/rustdesk-server-s6:latest
ports:
- "21114:21114"
- "21115:21115"
- "21116:21116"
- "21116:21116/udp"
- "21117:21117"
- "21118:21118"
- "21119:21119"
environment:
- RELAY=${SERVER_IP}:21117
- ENCRYPTED_ONLY=1
- MUST_LOGIN=N
- TZ=Asia/Shanghai
- RUSTDESK_API_RUSTDESK_ID_SERVER=${SERVER_IP}:21116
- RUSTDESK_API_RUSTDESK_RELAY_SERVER=${SERVER_IP}:21117
- RUSTDESK_API_RUSTDESK_API_SERVER=http://${SERVER_IP}:21114
# 核心:自动注入读取到的 Key
- RUSTDESK_API_KEY_FILE=/data/id_ed25519.pub
- KEY=${CAPTURED_KEY}
- RUSTDESK_API_RUSTDESK_KEY=${CAPTURED_KEY}
- RUSTDESK_API_JWT_KEY=${JWT_KEY}
volumes:
- ./server:/data
- ./api:/app/data
restart: unless-stopped
stdin_open: true
tty: true
EOF
# --- 5. 阶段三:正式上线 ---
echo "阶段 3:启动正式服务..."
docker compose up -d --force-recreate
# 在容器重建后设置权限,确保 API 能读取新生成的文件
chmod -R 777 "$BASE_DIR/server" "$BASE_DIR/api"
echo "------------------------------------------------"
echo "✅ 自动闭环部署成功!"
echo "服务器 IP: ${SERVER_IP}"
echo "捕获到的 Key: ${CAPTURED_KEY:0:30}..."
echo "管理后台: http://${SERVER_IP}:21114"
echo "------------------------------------------------"
# 最终健康检查
echo "等待服务初始化(10秒)..."
sleep 10
# 检查容器状态
if ! docker ps | grep -q rustdesk-server; then
echo "❌ 错误:容器未运行!"
echo "容器日志:"
docker logs rustdesk-server 2>&1 | tail -30
exit 1
fi
# 使用 docker exec 检查端口监听
PORT_CHECK=$(docker exec rustdesk-server sh -c "ss -tlnp 2>/dev/null || netstat -tlnp 2>/dev/null || echo 'no-tool'" 2>/dev/null || echo "check-failed")
if echo "$PORT_CHECK" | grep -q ":21114"; then
echo "✅ 状态:API 服务已启动,端口 21114 正在监听。"
else
echo "⚠️ 警告:API 端口检测未通过,请检查日志确认服务状态。"
echo "容器日志 (最后30行):"
docker logs rustdesk-server 2>&1 | tail -30
fi
echo ""
echo "=== 部署信息 ==="
echo "服务器 IP: ${SERVER_IP}"
echo "ID Server: ${SERVER_IP}:21116"
echo "Relay Server: ${SERVER_IP}:21117"
echo "API Server: http://${SERVER_IP}:21114"
echo ""
echo "=== 常用命令 ==="
echo "查看日志: docker logs -f rustdesk-server"
echo "停止服务: docker compose down"
echo "重启服务: docker compose restart"
echo ""
echo "=== 防火墙/安全组端口 ==="
echo "请确保以下端口已开放:21114, 21115, 21116, 21117, 21118, 21119"