229 lines
5.9 KiB
Bash
229 lines
5.9 KiB
Bash
#!/bin/bash
|
||
|
||
# 设置变量
|
||
DATA_DIR="/data"
|
||
SCRIPT_DIR="/boot/脚本"
|
||
COMPOSE_FILE="$SCRIPT_DIR/ru.yaml"
|
||
|
||
# 检查是否以 root 权限运行
|
||
if [ "$EUID" -ne 0 ]; then
|
||
echo "请使用 sudo 运行此脚本"
|
||
exit 1
|
||
fi
|
||
|
||
# 函数:彻底清理 Docker 资源
|
||
cleanup_docker() {
|
||
echo "清理 Docker 资源..."
|
||
|
||
# 停止并删除所有相关容器
|
||
docker stop nginx-proxy-manager 2>/dev/null || true
|
||
docker rm nginx-proxy-manager 2>/dev/null || true
|
||
|
||
# 删除 Docker Compose 项目
|
||
docker compose -p nginx down 2>/dev/null || true
|
||
|
||
# 清理网络
|
||
docker network prune -f
|
||
|
||
# 检查并删除占用端口的僵尸容器
|
||
echo "检查占用端口的容器..."
|
||
docker ps -a --format "table {{.Names}}\t{{.Ports}}" | grep -E "(80|81|443)" || echo "未发现明显端口冲突"
|
||
}
|
||
|
||
# 函数:更准确的端口检查
|
||
check_port_advanced() {
|
||
local port=$1
|
||
echo "深度检查端口 $port ..."
|
||
|
||
# 方法1: netstat
|
||
if netstat -tulpn 2>/dev/null | grep -q ":${port} "; then
|
||
echo "netstat 发现端口 $port 被占用"
|
||
netstat -tulpn | grep ":${port} "
|
||
return 1
|
||
fi
|
||
|
||
# 方法2: ss
|
||
if ss -tulpn 2>/dev/null | grep -q ":${port} "; then
|
||
echo "ss 发现端口 $port 被占用"
|
||
ss -tulpn | grep ":${port} "
|
||
return 1
|
||
fi
|
||
|
||
# 方法3: lsof
|
||
if lsof -i :${port} 2>/dev/null | grep -q "LISTEN"; then
|
||
echo "lsof 发现端口 $port 被占用"
|
||
lsof -i :${port}
|
||
return 1
|
||
fi
|
||
|
||
# 方法4: 检查 Docker 容器映射
|
||
if docker ps --format "table {{.Names}}\t{{.Ports}}" 2>/dev/null | grep -q ":${port}->"; then
|
||
echo "Docker 容器正在使用端口 $port"
|
||
docker ps --format "table {{.Names}}\t{{.Ports}}" | grep ":${port}->"
|
||
return 1
|
||
fi
|
||
|
||
echo "端口 $port 可用"
|
||
return 0
|
||
}
|
||
|
||
# 函数:使用备用端口部署
|
||
deploy_with_alternate_ports() {
|
||
local http_port="8080"
|
||
local admin_port="8081"
|
||
local https_port="8443"
|
||
|
||
echo "使用备用端口部署: HTTP=$http_port, 管理界面=$admin_port, HTTPS=$https_port"
|
||
|
||
# 创建配置
|
||
cat > "$COMPOSE_FILE" << EOF
|
||
# Nginx Proxy Manager 配置(备用端口)
|
||
services:
|
||
app:
|
||
image: 'docker.io/jc21/nginx-proxy-manager:latest'
|
||
container_name: nginx-proxy-manager
|
||
restart: unless-stopped
|
||
ports:
|
||
- '${http_port}:80'
|
||
- '${admin_port}:81'
|
||
- '${https_port}:443'
|
||
volumes:
|
||
- ./data:/data
|
||
- ./letsencrypt:/etc/letsencrypt
|
||
environment:
|
||
- DISABLE_IPV6=false
|
||
EOF
|
||
|
||
deploy_service $http_port $admin_port $https_port
|
||
}
|
||
|
||
# 函数:部署服务
|
||
deploy_service() {
|
||
local http_port=$1
|
||
local admin_port=$2
|
||
local https_port=$3
|
||
|
||
# 切换到脚本目录
|
||
cd "$SCRIPT_DIR" || exit 1
|
||
|
||
# 检查 Docker 是否运行
|
||
if ! systemctl is-active --quiet docker; then
|
||
echo "启动 Docker 服务..."
|
||
systemctl start docker
|
||
sleep 5
|
||
fi
|
||
|
||
# 部署服务
|
||
echo "启动 Nginx Proxy Manager..."
|
||
docker compose -p nginx -f "$COMPOSE_FILE" up -d
|
||
|
||
if [ $? -eq 0 ]; then
|
||
echo "等待服务启动..."
|
||
sleep 10
|
||
|
||
SERVER_IP=$(hostname -I | awk '{print $1}')
|
||
echo "=================================================="
|
||
echo "✅ Nginx Proxy Manager 部署成功!"
|
||
echo "管理界面: http://${SERVER_IP}:${admin_port}"
|
||
echo "HTTP 端口: ${http_port}"
|
||
echo "HTTPS 端口: ${https_port}"
|
||
echo "初始账号: admin@example.com"
|
||
echo "初始密码: changeme"
|
||
echo "=================================================="
|
||
else
|
||
echo "❌ 容器启动失败"
|
||
echo "检查 Docker 日志:docker logs nginx-proxy-manager"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# 主程序
|
||
echo "创建必要的目录..."
|
||
mkdir -p "$DATA_DIR"
|
||
mkdir -p "$SCRIPT_DIR"
|
||
|
||
# 显示当前状态
|
||
echo "=== 系统状态检查 ==="
|
||
check_port_advanced 80
|
||
check_port_advanced 81
|
||
check_port_advanced 443
|
||
|
||
echo ""
|
||
echo "=== Docker 状态 ==="
|
||
docker ps -a | grep nginx || echo "未发现 nginx 相关容器"
|
||
|
||
echo ""
|
||
echo "请选择部署方案:"
|
||
echo "1) 彻底清理后使用默认端口重试"
|
||
echo "2) 直接使用备用端口 (8080, 8081, 8443) - 推荐"
|
||
echo "3) 手动指定端口"
|
||
echo "4) 退出"
|
||
|
||
read -p "请输入选择 (1-4): " choice
|
||
|
||
case $choice in
|
||
1)
|
||
echo "执行彻底清理并使用默认端口..."
|
||
cleanup_docker
|
||
sleep 3
|
||
|
||
# 使用默认端口
|
||
cat > "$COMPOSE_FILE" << EOF
|
||
services:
|
||
app:
|
||
image: 'docker.io/jc21/nginx-proxy-manager:latest'
|
||
container_name: nginx-proxy-manager
|
||
restart: unless-stopped
|
||
ports:
|
||
- '80:80'
|
||
- '81:81'
|
||
- '443:443'
|
||
volumes:
|
||
- ./data:/data
|
||
- ./letsencrypt:/etc/letsencrypt
|
||
EOF
|
||
deploy_service 80 81 443
|
||
;;
|
||
2)
|
||
cleanup_docker
|
||
deploy_with_alternate_ports
|
||
;;
|
||
3)
|
||
echo "请手动指定端口:"
|
||
read -p "HTTP 端口 (推荐 8080): " custom_http
|
||
read -p "管理界面端口 (推荐 8081): " custom_admin
|
||
read -p "HTTPS 端口 (推荐 8443): " custom_https
|
||
|
||
HTTP_PORT=${custom_http:-8080}
|
||
ADMIN_PORT=${custom_admin:-8081}
|
||
HTTPS_PORT=${custom_https:-8443}
|
||
|
||
cleanup_docker
|
||
|
||
cat > "$COMPOSE_FILE" << EOF
|
||
services:
|
||
app:
|
||
image: 'docker.io/jc21/nginx-proxy-manager:latest'
|
||
container_name: nginx-proxy-manager
|
||
restart: unless-stopped
|
||
ports:
|
||
- '${HTTP_PORT}:80'
|
||
- '${ADMIN_PORT}:81'
|
||
- '${HTTPS_PORT}:443'
|
||
volumes:
|
||
- ./data:/data
|
||
- ./letsencrypt:/etc/letsencrypt
|
||
EOF
|
||
deploy_service $HTTP_PORT $ADMIN_PORT $HTTPS_PORT
|
||
;;
|
||
4)
|
||
echo "退出脚本"
|
||
exit 0
|
||
;;
|
||
*)
|
||
echo "无效选择,使用备用端口"
|
||
cleanup_docker
|
||
deploy_with_alternate_ports
|
||
;;
|
||
esac
|