feat: 添加智能端口检测和Nginx虚拟主机支持 (v4.0)
新增功能: - 智能识别占用端口的进程(Nginx/Apache/其他) - 支持Nginx虚拟主机模式,多网站共用80/443端口 - 根据不同进程提供针对性解决方案 - 优化用户交互体验,提供清晰的选项说明 改进内容: - 新增check_port_status()函数识别进程类型 - 改进configure_ports()函数支持虚拟主机选择 - 添加SHARE_NGINX标志跟踪部署模式 - 443端口智能继承80端口的选择 技术要点: - Nginx占用端口时提供共用选项(推荐) - Apache占用时提示冲突并给出解决方案 - 其他进程占用时引导用户更换端口 - 完整保留v3.0的CORS双重来源支持 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
322
install.sh
322
install.sh
@@ -648,9 +648,10 @@ install_pm2() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# 端口检测和配置
|
# 智能端口检测和配置
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
|
# 检查端口是否可用(保留用于兼容性)
|
||||||
check_port_available() {
|
check_port_available() {
|
||||||
local port=$1
|
local port=$1
|
||||||
if command -v netstat &> /dev/null; then
|
if command -v netstat &> /dev/null; then
|
||||||
@@ -665,22 +666,188 @@ check_port_available() {
|
|||||||
return 0 # 端口可用
|
return 0 # 端口可用
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 智能检测端口状态和占用进程
|
||||||
|
check_port_status() {
|
||||||
|
local port=$1
|
||||||
|
|
||||||
|
# 1. 检查端口是否被监听
|
||||||
|
if command -v netstat &> /dev/null; then
|
||||||
|
if ! netstat -tuln 2>/dev/null | grep -q ":${port} "; then
|
||||||
|
echo "available"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
elif command -v ss &> /dev/null; then
|
||||||
|
if ! ss -tuln 2>/dev/null | grep -q ":${port} "; then
|
||||||
|
echo "available"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "available"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. 端口被占用,检查是什么进程
|
||||||
|
local process=""
|
||||||
|
|
||||||
|
if command -v netstat &> /dev/null; then
|
||||||
|
process=$(netstat -tulnp 2>/dev/null | grep ":${port} " | awk '{print $7}' | cut -d'/' -f2 | head -1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$process" ]] && command -v ss &> /dev/null; then
|
||||||
|
process=$(ss -tulnp 2>/dev/null | grep ":${port} " | grep -oP '\".*?\"' | tr -d '"' | cut -d',' -f1 | head -1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3. 根据进程返回状态
|
||||||
|
if [[ -z "$process" ]]; then
|
||||||
|
# 无法获取进程名(可能权限不足)
|
||||||
|
echo "occupied"
|
||||||
|
return 1
|
||||||
|
elif [[ "$process" == "nginx" ]] || [[ "$process" =~ ^nginx: ]]; then
|
||||||
|
# Nginx占用
|
||||||
|
echo "nginx"
|
||||||
|
return 1
|
||||||
|
elif [[ "$process" == "apache2" ]] || [[ "$process" == "httpd" ]] || [[ "$process" =~ apache ]]; then
|
||||||
|
# Apache占用
|
||||||
|
echo "apache"
|
||||||
|
return 2
|
||||||
|
else
|
||||||
|
# 其他进程
|
||||||
|
echo "other:$process"
|
||||||
|
return 3
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 改进的端口配置函数
|
||||||
configure_ports() {
|
configure_ports() {
|
||||||
print_step "端口配置"
|
print_step "智能端口配置"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# 检测80端口
|
# 全局标志:是否共用Nginx端口
|
||||||
if ! check_port_available 80; then
|
SHARE_NGINX=false
|
||||||
print_warning "检测到 80 端口已被占用"
|
|
||||||
echo ""
|
|
||||||
echo "80端口被其他服务占用,您可以:"
|
|
||||||
echo -e "${GREEN}[1]${NC} 使用其他HTTP端口 (例如: 8080, 8888)"
|
|
||||||
echo -e "${GREEN}[2]${NC} 停止占用80端口的服务"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
read -p "请选择 [1-2]: " port_choice < /dev/tty
|
# ========== 检测80端口 ==========
|
||||||
|
port_80_status=$(check_port_status 80)
|
||||||
|
|
||||||
|
case $port_80_status in
|
||||||
|
"available")
|
||||||
|
print_success "80 端口可用"
|
||||||
|
HTTP_PORT=80
|
||||||
|
;;
|
||||||
|
|
||||||
|
"nginx")
|
||||||
|
print_info "检测到 Nginx 已占用 80 端口"
|
||||||
|
echo ""
|
||||||
|
echo "🎯 好消息:可以通过虚拟主机配置与现有Nginx共用此端口!"
|
||||||
|
echo ""
|
||||||
|
echo "请选择部署方式:"
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}[1]${NC} 共用80端口(推荐)"
|
||||||
|
echo " ✅ 需要配置不同的域名"
|
||||||
|
echo " ✅ 访问: http://your-domain.com"
|
||||||
|
echo " ✅ 不需要端口号"
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}[2]${NC} 使用其他HTTP端口"
|
||||||
|
echo " ℹ️ 独立端口"
|
||||||
|
echo " ℹ️ 访问: http://your-domain.com:8080"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -p "请选择 [1-2]: " choice < /dev/tty
|
||||||
|
|
||||||
|
if [[ "$choice" == "1" ]]; then
|
||||||
|
HTTP_PORT=80
|
||||||
|
SHARE_NGINX=true
|
||||||
|
print_success "将与现有Nginx共用80端口(虚拟主机模式)"
|
||||||
|
print_info "提示: 请确保使用不同的域名区分站点"
|
||||||
|
break
|
||||||
|
elif [[ "$choice" == "2" ]]; then
|
||||||
|
# 选择其他端口的逻辑
|
||||||
|
while true; do
|
||||||
|
read -p "请输入HTTP端口 [建议: 8080]: " custom_port < /dev/tty
|
||||||
|
custom_port=${custom_port:-8080}
|
||||||
|
|
||||||
|
if [[ ! "$custom_port" =~ ^[0-9]+$ ]] || [[ $custom_port -lt 1024 ]] || [[ $custom_port -gt 65535 ]]; then
|
||||||
|
print_error "端口范围: 1024-65535"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! check_port_available $custom_port; then
|
||||||
|
print_error "端口 $custom_port 已被占用,请选择其他端口"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
HTTP_PORT=$custom_port
|
||||||
|
print_success "将使用 HTTP 端口: $HTTP_PORT"
|
||||||
|
break
|
||||||
|
done
|
||||||
|
break
|
||||||
|
else
|
||||||
|
print_error "无效选项,请重新选择"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
|
||||||
|
"apache")
|
||||||
|
print_warning "检测到 Apache 已占用 80 端口"
|
||||||
|
echo ""
|
||||||
|
echo "⚠️ Apache和Nginx不能同时监听同一端口"
|
||||||
|
echo ""
|
||||||
|
echo "请选择解决方案:"
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}[1]${NC} 停止Apache,改用Nginx"
|
||||||
|
echo " ⚠️ 需要迁移Apache配置"
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}[2]${NC} 使用其他HTTP端口(推荐)"
|
||||||
|
echo " ✅ 不影响现有Apache服务"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -p "请选择 [1-2]: " choice < /dev/tty
|
||||||
|
|
||||||
|
if [[ "$choice" == "1" ]]; then
|
||||||
|
print_info "正在停止Apache..."
|
||||||
|
systemctl stop apache2 2>/dev/null || systemctl stop httpd 2>/dev/null || true
|
||||||
|
systemctl disable apache2 2>/dev/null || systemctl disable httpd 2>/dev/null || true
|
||||||
|
HTTP_PORT=80
|
||||||
|
print_success "Apache已停止,将使用80端口"
|
||||||
|
break
|
||||||
|
elif [[ "$choice" == "2" ]]; then
|
||||||
|
# 选择其他端口
|
||||||
|
while true; do
|
||||||
|
read -p "请输入HTTP端口 [建议: 8080]: " custom_port < /dev/tty
|
||||||
|
custom_port=${custom_port:-8080}
|
||||||
|
|
||||||
|
if [[ ! "$custom_port" =~ ^[0-9]+$ ]] || [[ $custom_port -lt 1024 ]] || [[ $custom_port -gt 65535 ]]; then
|
||||||
|
print_error "端口范围: 1024-65535"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! check_port_available $custom_port; then
|
||||||
|
print_error "端口 $custom_port 已被占用,请选择其他端口"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
HTTP_PORT=$custom_port
|
||||||
|
print_success "将使用 HTTP 端口: $HTTP_PORT"
|
||||||
|
break
|
||||||
|
done
|
||||||
|
break
|
||||||
|
else
|
||||||
|
print_error "无效选项,请重新选择"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
|
||||||
|
"occupied"|other:*)
|
||||||
|
process=${port_80_status#other:}
|
||||||
|
if [[ "$port_80_status" == "occupied" ]]; then
|
||||||
|
print_warning "80 端口已被占用(无法识别进程)"
|
||||||
|
else
|
||||||
|
print_warning "80 端口被进程 ${process} 占用"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo "请选择其他HTTP端口"
|
||||||
|
|
||||||
if [[ "$port_choice" == "1" ]]; then
|
|
||||||
while true; do
|
while true; do
|
||||||
read -p "请输入HTTP端口 [建议: 8080]: " custom_port < /dev/tty
|
read -p "请输入HTTP端口 [建议: 8080]: " custom_port < /dev/tty
|
||||||
custom_port=${custom_port:-8080}
|
custom_port=${custom_port:-8080}
|
||||||
@@ -699,47 +866,113 @@ configure_ports() {
|
|||||||
print_success "将使用 HTTP 端口: $HTTP_PORT"
|
print_success "将使用 HTTP 端口: $HTTP_PORT"
|
||||||
break
|
break
|
||||||
done
|
done
|
||||||
else
|
;;
|
||||||
print_info "请手动停止占用80端口的服务后重新运行此脚本"
|
esac
|
||||||
echo ""
|
|
||||||
print_info "查看端口占用: netstat -tunlp | grep :80"
|
|
||||||
print_info "或者: ss -tunlp | grep :80"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
print_success "80 端口可用"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 检测443端口(仅在使用HTTPS时需要)
|
echo ""
|
||||||
|
|
||||||
|
# ========== 检测443端口(仅在使用HTTPS时需要)==========
|
||||||
if [[ "$USE_DOMAIN" == "true" ]] && [[ "$SSL_METHOD" != "8" ]]; then
|
if [[ "$USE_DOMAIN" == "true" ]] && [[ "$SSL_METHOD" != "8" ]]; then
|
||||||
if ! check_port_available 443; then
|
port_443_status=$(check_port_status 443)
|
||||||
print_warning "检测到 443 端口已被占用"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
while true; do
|
case $port_443_status in
|
||||||
read -p "请输入HTTPS端口 [建议: 8443]: " custom_https_port < /dev/tty
|
"available")
|
||||||
custom_https_port=${custom_https_port:-8443}
|
print_success "443 端口可用"
|
||||||
|
HTTPS_PORT=443
|
||||||
|
;;
|
||||||
|
|
||||||
if [[ ! "$custom_https_port" =~ ^[0-9]+$ ]] || [[ $custom_https_port -lt 1024 ]] || [[ $custom_https_port -gt 65535 ]]; then
|
"nginx")
|
||||||
print_error "端口范围: 1024-65535"
|
print_info "检测到 Nginx 已占用 443 端口"
|
||||||
continue
|
echo ""
|
||||||
|
|
||||||
|
if [[ "$SHARE_NGINX" == "true" ]]; then
|
||||||
|
# 如果HTTP端口也是共用的,默认继续共用
|
||||||
|
echo "🎯 将继续与现有Nginx共用443端口(虚拟主机模式)"
|
||||||
|
HTTPS_PORT=443
|
||||||
|
print_success "将与现有Nginx共用443端口"
|
||||||
|
else
|
||||||
|
echo "请选择部署方式:"
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}[1]${NC} 共用443端口"
|
||||||
|
echo " ✅ 需要配置不同的域名"
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}[2]${NC} 使用其他HTTPS端口"
|
||||||
|
echo " ℹ️ 独立端口(如8443)"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -p "请选择 [1-2]: " choice < /dev/tty
|
||||||
|
|
||||||
|
if [[ "$choice" == "1" ]]; then
|
||||||
|
HTTPS_PORT=443
|
||||||
|
SHARE_NGINX=true
|
||||||
|
print_success "将与现有Nginx共用443端口"
|
||||||
|
break
|
||||||
|
elif [[ "$choice" == "2" ]]; then
|
||||||
|
# 选择其他端口
|
||||||
|
while true; do
|
||||||
|
read -p "请输入HTTPS端口 [建议: 8443]: " custom_https_port < /dev/tty
|
||||||
|
custom_https_port=${custom_https_port:-8443}
|
||||||
|
|
||||||
|
if [[ ! "$custom_https_port" =~ ^[0-9]+$ ]] || [[ $custom_https_port -lt 1024 ]] || [[ $custom_https_port -gt 65535 ]]; then
|
||||||
|
print_error "端口范围: 1024-65535"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! check_port_available $custom_https_port; then
|
||||||
|
print_error "端口 $custom_https_port 已被占用,请选择其他端口"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
HTTPS_PORT=$custom_https_port
|
||||||
|
print_success "将使用 HTTPS 端口: $HTTPS_PORT"
|
||||||
|
break
|
||||||
|
done
|
||||||
|
break
|
||||||
|
else
|
||||||
|
print_error "无效选项,请重新选择"
|
||||||
|
fi
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
if ! check_port_available $custom_https_port; then
|
"apache"|"occupied"|other:*)
|
||||||
print_error "端口 $custom_https_port 已被占用,请选择其他端口"
|
# Apache或其他进程占用443,需要换端口
|
||||||
continue
|
if [[ "$port_443_status" == "apache" ]]; then
|
||||||
|
print_warning "检测到 Apache 已占用 443 端口"
|
||||||
|
elif [[ "$port_443_status" == "occupied" ]]; then
|
||||||
|
print_warning "443 端口已被占用"
|
||||||
|
else
|
||||||
|
process=${port_443_status#other:}
|
||||||
|
print_warning "443 端口被进程 ${process} 占用"
|
||||||
fi
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
HTTPS_PORT=$custom_https_port
|
while true; do
|
||||||
print_success "将使用 HTTPS 端口: $HTTPS_PORT"
|
read -p "请输入HTTPS端口 [建议: 8443]: " custom_https_port < /dev/tty
|
||||||
break
|
custom_https_port=${custom_https_port:-8443}
|
||||||
done
|
|
||||||
else
|
if [[ ! "$custom_https_port" =~ ^[0-9]+$ ]] || [[ $custom_https_port -lt 1024 ]] || [[ $custom_https_port -gt 65535 ]]; then
|
||||||
print_success "443 端口可用"
|
print_error "端口范围: 1024-65535"
|
||||||
fi
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! check_port_available $custom_https_port; then
|
||||||
|
print_error "端口 $custom_https_port 已被占用,请选择其他端口"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
HTTPS_PORT=$custom_https_port
|
||||||
|
print_success "将使用 HTTPS 端口: $HTTPS_PORT"
|
||||||
|
break
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 检测后端端口
|
# ========== 检测后端端口 ==========
|
||||||
if ! check_port_available 40001; then
|
if ! check_port_available 40001; then
|
||||||
print_warning "检测到 40001 端口已被占用"
|
print_warning "检测到 40001 端口已被占用"
|
||||||
echo ""
|
echo ""
|
||||||
@@ -773,6 +1006,9 @@ configure_ports() {
|
|||||||
echo " - HTTPS端口: $HTTPS_PORT"
|
echo " - HTTPS端口: $HTTPS_PORT"
|
||||||
fi
|
fi
|
||||||
echo " - 后端端口: $BACKEND_PORT"
|
echo " - 后端端口: $BACKEND_PORT"
|
||||||
|
if [[ "$SHARE_NGINX" == "true" ]]; then
|
||||||
|
echo " - 模式: 虚拟主机共用端口 ✅"
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user