238 lines
6.7 KiB
Bash
238 lines
6.7 KiB
Bash
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
|
|
# ==================================================
|
|
# Nginx Proxy Manager 一键安装脚本
|
|
# 版本: 1.0
|
|
# 描述: 自动部署 Nginx Proxy Manager 反向代理管理工具
|
|
# ==================================================
|
|
|
|
# 脚本配置
|
|
APP_NAME="nginx-proxy-manager"
|
|
SCRIPT_NAME="deploy_nginx_proxy_manager.sh"
|
|
WORK_DIR="/data"
|
|
|
|
# 颜色定义
|
|
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"
|
|
}
|
|
|
|
# 错误处理函数
|
|
error_exit() {
|
|
log_error "$1"
|
|
exit 1
|
|
}
|
|
|
|
# 清理函数
|
|
cleanup() {
|
|
log_info "正在清理临时资源..."
|
|
# 可以在这里添加清理代码
|
|
}
|
|
|
|
# 信号处理
|
|
trap cleanup EXIT INT TERM
|
|
|
|
# ==================================================
|
|
# 环境检查
|
|
# ==================================================
|
|
|
|
log_info "开始检查运行环境..."
|
|
|
|
# 检查是否为 root 用户
|
|
if [[ $EUID -eq 0 ]]; then
|
|
log_warning "建议使用非 root 用户执行此脚本,但将继续执行..."
|
|
fi
|
|
|
|
# 检查 Docker 是否安装
|
|
if ! command -v docker &> /dev/null; then
|
|
error_exit "Docker 未安装,请先安装 Docker"
|
|
fi
|
|
|
|
# 检查 Docker 服务状态
|
|
if ! systemctl is-active --quiet docker && ! systemctl is-active --quiet docker.service; then
|
|
log_info "尝试启动 Docker 服务..."
|
|
if ! sudo systemctl start docker 2>/dev/null; then
|
|
error_exit "Docker 服务未运行且无法启动"
|
|
fi
|
|
fi
|
|
|
|
# 测试 Docker 是否正常工作
|
|
if ! docker info &> /dev/null; then
|
|
error_exit "Docker 无法正常工作,请检查 Docker 服务状态"
|
|
fi
|
|
|
|
log_success "环境检查通过"
|
|
|
|
# ==================================================
|
|
# 目录准备
|
|
# ==================================================
|
|
|
|
log_info "正在准备工作目录..."
|
|
|
|
# 创建并切换到工作目录
|
|
if [[ ! -d "$WORK_DIR" ]]; then
|
|
log_info "创建工作目录: $WORK_DIR"
|
|
if ! sudo mkdir -p "$WORK_DIR" 2>/dev/null && ! mkdir -p "$WORK_DIR"; then
|
|
error_exit "无法创建目录 $WORK_DIR,请检查权限"
|
|
fi
|
|
fi
|
|
|
|
# 进入工作目录
|
|
cd "$WORK_DIR" || error_exit "无法进入目录 $WORK_DIR"
|
|
|
|
# 创建必要的子目录
|
|
for dir in nginx-proxy-manager/data nginx-proxy-manager/letsencrypt; do
|
|
if [[ ! -d "$dir" ]]; then
|
|
log_info "创建目录: $WORK_DIR/$dir"
|
|
mkdir -p "$dir" || error_exit "无法创建目录 $dir"
|
|
fi
|
|
done
|
|
|
|
log_success "目录准备完成"
|
|
|
|
# ==================================================
|
|
# 停止并删除现有容器(如果存在)
|
|
# ==================================================
|
|
|
|
log_info "检查现有容器..."
|
|
|
|
if docker ps -a --format "table {{.Names}}" | grep -q "^${APP_NAME}$"; then
|
|
log_info "发现已存在的容器,正在停止并删除..."
|
|
|
|
# 停止容器
|
|
if docker ps --format "table {{.Names}}" | grep -q "^${APP_NAME}$"; then
|
|
docker stop "$APP_NAME" || log_warning "停止容器失败,但将继续执行"
|
|
sleep 5
|
|
fi
|
|
|
|
# 删除容器
|
|
docker rm "$APP_NAME" || error_exit "删除旧容器失败"
|
|
log_success "旧容器清理完成"
|
|
fi
|
|
|
|
# ==================================================
|
|
# 拉取 Docker 镜像
|
|
# ==================================================
|
|
|
|
log_info "正在拉取 Nginx Proxy Manager 镜像..."
|
|
|
|
# 设置重试机制
|
|
MAX_RETRIES=3
|
|
RETRY_COUNT=0
|
|
|
|
while [[ $RETRY_COUNT -lt $MAX_RETRIES ]]; do
|
|
if docker pull docker.io/jc21/nginx-proxy-manager:latest; then
|
|
log_success "镜像拉取成功"
|
|
break
|
|
else
|
|
RETRY_COUNT=$((RETRY_COUNT + 1))
|
|
if [[ $RETRY_COUNT -eq $MAX_RETRIES ]]; then
|
|
error_exit "镜像拉取失败,已达到最大重试次数"
|
|
else
|
|
log_warning "镜像拉取失败,第 $RETRY_COUNT 次重试..."
|
|
sleep 10
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# ==================================================
|
|
# 部署容器
|
|
# ==================================================
|
|
|
|
log_info "正在启动 Nginx Proxy Manager 容器..."
|
|
|
|
DOCKER_RUN_CMD="docker run -d \
|
|
--name $APP_NAME \
|
|
--restart=unless-stopped \
|
|
-p 80:80 \
|
|
-p 81:81 \
|
|
-p 443:443 \
|
|
-v $WORK_DIR/nginx-proxy-manager/data:/data \
|
|
-v $WORK_DIR/nginx-proxy-manager/letsencrypt:/etc/letsencrypt \
|
|
docker.io/jc21/nginx-proxy-manager:latest"
|
|
|
|
log_info "执行命令: $DOCKER_RUN_CMD"
|
|
|
|
if ! eval "$DOCKER_RUN_CMD"; then
|
|
error_exit "容器启动失败"
|
|
fi
|
|
|
|
log_success "容器启动命令执行成功"
|
|
|
|
# ==================================================
|
|
# 等待并验证服务状态
|
|
# ==================================================
|
|
|
|
log_info "等待服务启动..."
|
|
sleep 10
|
|
|
|
# 检查容器状态
|
|
if ! docker ps --format "table {{.Names}}\t{{.Status}}" | grep -q "$APP_NAME"; then
|
|
error_exit "容器未运行,请检查日志: docker logs $APP_NAME"
|
|
fi
|
|
|
|
CONTAINER_STATUS=$(docker inspect --format='{{.State.Status}}' "$APP_NAME" 2>/dev/null || echo "unknown")
|
|
if [[ "$CONTAINER_STATUS" != "running" ]]; then
|
|
error_exit "容器状态异常: $CONTAINER_STATUS,请检查日志: docker logs $APP_NAME"
|
|
fi
|
|
|
|
# 检查服务端口
|
|
PORTS=(80 81 443)
|
|
for port in "${PORTS[@]}"; do
|
|
if ! ss -tln | grep -q ":$port "; then
|
|
log_warning "端口 $port 未监听,服务可能仍在启动中"
|
|
fi
|
|
done
|
|
|
|
log_success "Nginx Proxy Manager 部署完成!"
|
|
|
|
# ==================================================
|
|
# 显示部署信息
|
|
# ==================================================
|
|
|
|
echo
|
|
log_success "🎉 Nginx Proxy Manager 部署成功!"
|
|
echo
|
|
echo "═══════════════════════════════════════════════════════════════"
|
|
echo "访问地址: http://$(hostname -I | awk '{print $1}'):81"
|
|
echo "默认邮箱: admin@example.com"
|
|
echo "默认密码: changeme"
|
|
echo
|
|
echo "重要提示:"
|
|
echo "1. 首次登录后请立即修改默认密码"
|
|
echo "2. 管理界面运行在 81 端口"
|
|
echo "3. 数据存储位置: $WORK_DIR/nginx-proxy-manager/"
|
|
echo "4. 查看容器日志: docker logs $APP_NAME"
|
|
echo "5. 停止服务: docker stop $APP_NAME"
|
|
echo "6. 启动服务: docker start $APP_NAME"
|
|
echo "═══════════════════════════════════════════════════════════════"
|
|
echo
|
|
|
|
# 显示容器状态
|
|
log_info "当前容器状态:"
|
|
docker ps --filter "name=$APP_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
|
|
|
# 显示数据目录结构
|
|
log_info "数据目录结构:"
|
|
find "$WORK_DIR/nginx-proxy-manager" -type f -name "*" | head -10
|