#!/bin/bash # ========================================================================= # UniFi Network Application + MongoDB 集中式一键部署脚本 # 适用于 Debian 10/11/12/13(Trixie) 系统的云服务器 (VPS) # # 本版本修复: # ① Docker 官方源域名写错:download.docker.io -> download.docker.com # (.io 是 Docker Hub 镜像仓库域名,.com 才是 APT 源/GPG key 所在域名) # ② MongoDB 建用户时补上 mechanisms: ["SCRAM-SHA-1", "SCRAM-SHA-256"], # 否则 4.0+ 版本默认只生成 SCRAM-SHA-256 凭据,UniFi 容器内置的较旧 # Mongo 驱动如果只认 SCRAM-SHA-1 会直接认证失败 # ③ MEM_LIMIT/MEM_STARTUP 从 1024 上调到 2048,为后续管理更多分支/设备 # 留出余量 # ④ 清理 unifi-db 服务下不起作用的 MONGO_USER/PASS/DBNAME/AUTHSOURCE # (官方 mongo 镜像不认这几个变量,真正建号靠 init-mongo.js) # ⑤ 去掉过时的 version 字段,避免新版 Docker Compose 打印过时警告 # # ⚠️ 部署前请修改 MONGO_ROOT_PASS / MONGO_UNIFI_PASS 为你自己的强密码, # 下面写的是示例值,格式上跟真密码没区别,容易忘了改 # ========================================================================= # ---- 配置变量(保留 ROS 脚本变量定义,保持完全一致) ---- MONGO_ROOT_USER="root" MONGO_ROOT_PASS="rootpassword123" MONGO_UNIFI_USER="unifi" MONGO_UNIFI_PASS="unifipass123" MONGO_DBNAME="unifi" # Debian 部署路径定义 INSTALL_DIR="/opt/unifi" # 颜色输出定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' PLAIN='\033[0m' echo -e "${GREEN}=== UniFi VPS 部署开始 ===${PLAIN}" # ========================================================================= # Step 1: 权限检查 (必须为 root 执行) # ========================================================================= echo -e "${YELLOW}Step 1: 检查执行权限...${PLAIN}" if [ "$(id -u)" -ne 0 ]; then echo -e "${RED}错误:必须以 root 权限运行此脚本,请使用 sudo su 或以 root 用户登录运行。${PLAIN}" exit 1 fi echo -e "${GREEN}权限验证通过。${PLAIN}" # ========================================================================= # Step 2: 检查并安装 Docker 与 Docker Compose (高内聚低耦合容错方案) # ========================================================================= echo -e "${YELLOW}Step 2: 检查并安装 Docker 环境...${PLAIN}" # 2.1 清理残留的不可用外部 Docker 源,防止 apt 报错 echo -e "${YELLOW}正在清理可能损坏的外部 Docker 软件源...${PLAIN}" rm -f /etc/apt/sources.list.d/docker.list # 2.2 优先尝试使用 Debian 官方仓库提供的原生 docker.io 与 docker-compose 安装 # 这种方式能够 100% 绕过 download.docker.com 的 DNS 阻断,且完美适配 Debian Trixie (Debian 13) if ! command -v docker &> /dev/null; then echo -e "${YELLOW}开始通过 Debian 官方仓库安装 docker.io...${PLAIN}" apt-get update if apt-get install -y docker.io docker-compose; then echo -e "${GREEN}成功通过 Debian 官方仓库安装 Docker 及 Compose!${PLAIN}" else echo -e "${RED}Debian 官方仓库安装失败,尝试备用官方 Docker 软件源安装模式...${PLAIN}" # 官方源备用安装逻辑 apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release mkdir -p /etc/apt/keyrings # 尝试拉取官方 key (加入超时判定) if curl -fsSL --connect-timeout 10 https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg 2>/dev/null; then echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null apt-get update apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin else echo -e "${RED}错误:无法连接到官方 Docker 服务器,且本地源安装失败。请检查 VPS DNS 设定。${PLAIN}" exit 1 fi fi # 确保服务已启动 systemctl daemon-reload systemctl enable docker systemctl start docker else echo -e "${GREEN}Docker 已存在,跳过安装。${PLAIN}" fi # 2.3 智能识别并锁定 Docker Compose 运行指令 DOCKER_CMD="" if docker compose version &> /dev/null; then DOCKER_CMD="docker compose" echo -e "${GREEN}使用 Docker Compose V2 指令 (${DOCKER_CMD})。${PLAIN}" elif docker-compose version &> /dev/null; then DOCKER_CMD="docker-compose" echo -e "${GREEN}使用 Docker Compose V1 指令 (${DOCKER_CMD})。${PLAIN}" else echo -e "${YELLOW}未检测到 Docker Compose。正在尝试通过官方源或系统源追加安装...${PLAIN}" apt-get install -y docker-compose-plugin || apt-get install -y docker-compose if docker compose version &> /dev/null; then DOCKER_CMD="docker compose" else DOCKER_CMD="docker-compose" fi echo -e "${GREEN}确定使用 Compose 命令:${DOCKER_CMD}${PLAIN}" fi # ========================================================================= # Step 3: 创建数据目录 # ========================================================================= echo -e "${YELLOW}Step 3: 创建数据与初始化目录...${PLAIN}" mkdir -p "${INSTALL_DIR}/db" mkdir -p "${INSTALL_DIR}/config" mkdir -p "${INSTALL_DIR}/db-init" echo -e "${GREEN}目录结构已建立于 ${INSTALL_DIR} 下。${PLAIN}" # ========================================================================= # Step 4: 创写 MongoDB 数据库自引导脚本 (init-mongo.js) # ========================================================================= echo -e "${YELLOW}Step 4: 生成数据库自引导初始化脚本...${PLAIN}" # 此脚本在首次开机时自动在 admin 系统管理库中建立 unifi 账号,并赋予三个子库 (unifi, unifi_stat, unifi_audit) 的 dbOwner 权限 # mechanisms 显式同时保留 SCRAM-SHA-1 和 SCRAM-SHA-256: # MongoDB 4.0+ 默认只生成 SHA-256 凭据,UniFi 容器内置的 Mongo 驱动版本较旧, # 如果只认 SCRAM-SHA-1,缺了这行会直接认证失败 cat << EOF > "${INSTALL_DIR}/db-init/init-mongo.js" db.getSiblingDB("admin").createUser({ user: "${MONGO_UNIFI_USER}", pwd: "${MONGO_UNIFI_PASS}", roles: [ { role: "dbOwner", db: "${MONGO_DBNAME}" }, { role: "dbOwner", db: "${MONGO_DBNAME}_stat" }, { role: "dbOwner", db: "${MONGO_DBNAME}_audit" } ], mechanisms: ["SCRAM-SHA-1", "SCRAM-SHA-256"] }); EOF chmod 644 "${INSTALL_DIR}/db-init/init-mongo.js" echo -e "${GREEN}init-mongo.js 已经就绪。${PLAIN}" # ========================================================================= # Step 5: 自动组装并创写 docker-compose.yml 配置文件 # ========================================================================= echo -e "${YELLOW}Step 5: 生成 docker-compose.yml 配置文件...${PLAIN}" cat << EOF > "${INSTALL_DIR}/docker-compose.yml" services: unifi-db: image: mongo:4.4.18 container_name: unifi-db restart: unless-stopped environment: - MONGO_INITDB_ROOT_USERNAME=${MONGO_ROOT_USER} - MONGO_INITDB_ROOT_PASSWORD=${MONGO_ROOT_PASS} volumes: - ${INSTALL_DIR}/db:/data/db - ${INSTALL_DIR}/db-init/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro unifi-network-application: image: lscr.io/linuxserver/unifi-network-application:latest container_name: unifi-network-application restart: unless-stopped depends_on: - unifi-db environment: - PUID=1000 - PGID=1000 - TZ=Asia/Shanghai - MONGO_USER=${MONGO_UNIFI_USER} - MONGO_PASS=${MONGO_UNIFI_PASS} - MONGO_HOST=unifi-db - MONGO_PORT=27017 - MONGO_DBNAME=${MONGO_DBNAME} - MONGO_AUTHSOURCE=admin - MEM_LIMIT=2048 - MEM_STARTUP=2048 volumes: - ${INSTALL_DIR}/config:/config ports: - "8443:8443" - "8080:8080" - "3478:3478/udp" - "10001:10001/udp" EOF echo -e "${GREEN}docker-compose.yml 成功写入。${PLAIN}" # ========================================================================= # Step 6: 触发镜像拉取与容器编排启动 # ========================================================================= echo -e "${YELLOW}Step 6: 开始拉取镜像并后台启动容器(视 VPS 网速可能需要几分钟)...${PLAIN}" cd "${INSTALL_DIR}" $DOCKER_CMD pull $DOCKER_CMD up -d echo -e "${GREEN}容器已成功发起并运行!${PLAIN}" # ========================================================================= # Step 7: 检查并输出运行状态 # ========================================================================= echo -e "${YELLOW}Step 7: 确认容器运行状态...${PLAIN}" sleep 5 $DOCKER_CMD ps echo -e " ========================================================================= ${GREEN}🎉 UniFi Network Application 在 VPS 部署圆满成功!${PLAIN} ========================================================================= 1. 访问管理控制台 WebUI: 👉 ${GREEN}https://<你的VPS公网或带外IP>:8443${PLAIN} *(注:请在浏览器中信任自签名安全证书登录。)* 2. 数据库配置详情: - 库名:${MONGO_DBNAME} - 用户:${MONGO_UNIFI_USER} - 密码:${MONGO_UNIFI_PASS} 3. 容器数据维护根目录: - 配置文件与日志:${INSTALL_DIR}/config - 数据库文件:${INSTALL_DIR}/db 4. 运维命令参考: - 查看实时日志:cd ${INSTALL_DIR} && ${DOCKER_CMD} logs -f - 停止全部服务:cd ${INSTALL_DIR} && ${DOCKER_CMD} down - 重启全部服务:cd ${INSTALL_DIR} && ${DOCKER_CMD} restart ========================================================================= "