Files
dock/nginx
2025-11-17 13:45:21 +08:00

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