Files
dock/ru
2025-10-20 16:15:07 +08:00

305 lines
8.2 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# 设置错误处理
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查 Docker 是否安装
check_docker() {
if ! command -v docker &> /dev/null; then
log_error "Docker 未安装,请先安装 Docker"
exit 1
fi
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
log_error "Docker Compose 未安装"
exit 1
fi
log_success "Docker 环境检查通过"
}
# 创建目录结构
create_directories() {
local dirs=("/data" "/boot/脚本" "/data/rustdesk/server" "/data/rustdesk/api")
for dir in "${dirs[@]}"; do
if [ ! -d "$dir" ]; then
sudo mkdir -p "$dir"
log_info "创建目录: $dir"
else
log_info "目录已存在: $dir"
fi
done
}
# 生成随机密码
generate_password() {
local length=12
tr -dc 'A-Za-z0-9!@#$%' < /dev/urandom | head -c $length
}
# 获取用户输入
get_user_input() {
local default_project="rustdesk-server"
local default_port="21114"
# 读取项目名称
while true; do
read -p "请输入项目名称(默认: $default_project: " input_project
project_name=$(echo "$input_project" | xargs)
project_name=${project_name:-$default_project}
# 验证项目名称(只允许字母、数字、连字符)
if [[ "$project_name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
break
else
log_error "项目名称只能包含字母、数字、连字符和下划线"
fi
done
# 读取端口
while true; do
read -p "请输入主服务端口(默认: $default_port: " input_port
port=$(echo "$input_port" | xargs)
port=${port:-$default_port}
# 验证端口
if [[ "$port" =~ ^[0-9]+$ ]] && [ "$port" -ge 1024 ] && [ "$port" -le 65535 ]; then
break
else
log_error "端口号必须是 1024-65535 之间的数字"
fi
done
# 询问是否使用随机密码
read -p "是否生成随机管理员密码?(y/N): " use_random_pwd
if [[ "$use_random_pwd" =~ ^[Yy]$ ]]; then
admin_password=$(generate_password)
log_info "已生成随机密码"
else
while true; do
read -sp "请输入管理员密码: " admin_password
echo
if [ -n "$admin_password" ]; then
break
else
log_error "密码不能为空"
fi
done
fi
# 获取本机IP
local_ip=$(hostname -I | awk '{print $1}')
public_ip=$(curl -s ifconfig.me || echo "无法获取公网IP")
echo
log_info "配置摘要:"
log_info "项目名称: $project_name"
log_info "服务端口: $port"
log_info "管理员密码: ${admin_password:0:4}******"
log_info "本地IP: $local_ip"
log_info "公网IP: $public_ip"
echo
read -p "确认开始部署?(Y/n): " confirm
if [[ "$confirm" =~ ^[Nn]$ ]]; then
log_info "部署已取消"
exit 0
fi
}
# 生成 Docker Compose 配置文件
generate_compose_file() {
local file_path="/boot/脚本/rustdesk.yaml"
local project_name="$1"
local port="$2"
local admin_password="$3"
# 生成 JWT 密钥
local jwt_key=$(openssl rand -base64 32 2>/dev/null || echo "default_jwt_key_$(date +%s)")
cat > "$file_path" << EOF
# RustDesk Server 配置
# 生成时间: $(date)
# 项目名称: $project_name
networks:
rustdesk-net:
driver: bridge
services:
rustdesk-server:
container_name: ${project_name}-rustdesk
hostname: ${project_name}-server
image: lejianwen/rustdesk-server-s6:latest
ports:
- "${port}:21114" # API 服务器
- "21115:21115" # 其他服务
- "21116:21116" # ID 服务器
- "21117:21117" # 中继服务器
- "21118:21118" # 其他服务
- "21119:21119" # 其他服务
- "21116:21116/udp" # UDP 端口
environment:
- RELAY=127.0.0.1
- ENCRYPTED_ONLY=1
- MUST_LOGIN=n
- TZ=Asia/Shanghai
- RUSTDESK_API_RUSTDESK_ID_SERVER=127.0.0.1:21116
- RUSTDESK_API_RUSTDESK_RELAY_SERVER=127.0.0.1:21117
- RUSTDESK_API_RUSTDESK_API_SERVER=http://127.0.0.1:21114
- RUSTDESK_API_KEY_FILE=/data/id_ed25519.pub
- RUSTDESK_API_JWT_KEY=${jwt_key}
volumes:
- /data/rustdesk/server:/data
- /data/rustdesk/api:/app/data
networks:
- rustdesk-net
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:21114"]
interval: 30s
timeout: 10s
retries: 3
EOF
log_success "Docker Compose 配置文件已生成: $file_path"
}
# 部署服务
deploy_service() {
local project_name="$1"
local admin_password="$2"
local file_path="/boot/脚本/rustdesk.yaml"
log_info "开始部署 RustDesk 服务..."
# 使用 docker-compose 或 docker compose
local compose_cmd
if command -v docker-compose &> /dev/null; then
compose_cmd="docker-compose"
else
compose_cmd="docker compose"
fi
# 部署服务
sudo $compose_cmd -p "$project_name" -f "$file_path" up -d
log_info "等待服务启动..."
# 等待服务启动
local max_attempts=30
local attempt=1
while [ $attempt -le $max_attempts ]; do
if docker ps --filter "name=${project_name}-rustdesk" --format "table {{.Names}}\t{{.Status}}" | grep -q "Up"; then
log_success "RustDesk 服务启动成功"
break
fi
log_info "等待服务启动... ($attempt/$max_attempts)"
sleep 2
((attempt++))
done
if [ $attempt -gt $max_attempts ]; then
log_error "服务启动超时,请检查日志"
docker logs "${project_name}-rustdesk"
exit 1
fi
# 重置管理员密码
log_info "设置管理员密码..."
if docker exec "${project_name}-rustdesk" sh -c "./apimain reset-admin-pwd \"$admin_password\""; then
log_success "管理员密码设置成功"
else
log_warning "密码设置失败,可能需要手动设置"
fi
sleep 2
}
# 显示部署结果
show_deployment_info() {
local project_name="$1"
local port="$2"
local admin_password="$3"
local local_ip=$(hostname -I | awk '{print $1}')
echo
log_success "🎉 RustDesk 部署完成!"
echo
echo "=================== 访问信息 ==================="
echo -e "本地访问: ${GREEN}http://${local_ip}:${port}${NC}"
echo -e "公网访问: ${GREEN}请使用您的公网IP:${port}${NC}"
echo
echo "=================== 账号信息 ==================="
echo -e "管理员账号: ${GREEN}admin${NC}"
echo -e "管理员密码: ${GREEN}${admin_password}${NC}"
echo
echo "=================== 管理命令 ==================="
echo -e "查看服务状态: ${YELLOW}docker ps -f name=${project_name}${NC}"
echo -e "查看服务日志: ${YELLOW}docker logs ${project_name}-rustdesk${NC}"
echo -e "停止服务: ${YELLOW}sudo docker compose -p ${project_name} down${NC}"
echo -e "重启服务: ${YELLOW}sudo docker compose -p ${project_name} restart${NC}"
echo "================================================"
echo
log_warning "请确保防火墙已开放端口: ${port}, 21115-21119"
}
# 主函数
main() {
echo
log_info "开始 RustDesk 服务器部署"
echo "========================================"
# 检查 Docker
check_docker
# 创建目录
create_directories
# 获取用户输入
get_user_input
# 生成配置文件
generate_compose_file "$project_name" "$port" "$admin_password"
# 部署服务
deploy_service "$project_name" "$admin_password"
# 显示部署结果
show_deployment_info "$project_name" "$port" "$admin_password"
log_success "部署脚本执行完成"
}
# 脚本入口
main "$@"