#!/bin/bash # ============================================================ # PPQpanel 一键安装脚本 # 用法(用户复制这一行到自己的 Linux 服务器): # curl -sSL https://ppqmb.com/install.sh | bash # # 设计原则: # 1. 幂等——重复执行不会炸(能装第二次) # 2. 不依赖本地已有文件——全部从 PPQ_BASE_URL 拉 # 3. 官网二进制一个字节不改——升级能力完整保留 # 4. 定制全在数据层——升级零成本 # ============================================================ set -u PPQ_VERSION="1.0.0" PPQ_BASE_URL="${PPQ_BASE_URL:-https://ppqmb.com}" PANEL_PORT="${PANEL_PORT:-18080}" PANEL_ENTRANCE="${PANEL_ENTRANCE:-manage1p}" ADMIN_USER="${ADMIN_USER:-admin}" WORKDIR="/opt/ppq-panel" LOCAL_APP_STORE="/opt/1panel/resource/apps/local" IMAGES_TGZ="ppq-images-${PPQ_VERSION}.tar.gz" # ---------- 输出样式 ---------- c_green() { printf '\033[32m%s\033[0m\n' "$1"; } c_yellow() { printf '\033[33m%s\033[0m\n' "$1"; } c_red() { printf '\033[31m%s\033[0m\n' "$1"; } step() { printf '\n\033[36m==> %s\033[0m\n' "$1"; } cat <<'BANNER' ╔══════════════════════════════════════════════╗ ║ PPQpanel 一键安装程序 ║ ║ 啪啪雀面板 · 基于 1Panel v2 内核(GPL-3.0) ║ ╚══════════════════════════════════════════════╝ BANNER # ---------- 1. 环境检查 ---------- step "[1/8] 环境检查" if [ "$(id -u)" != "0" ]; then c_red "请用 root 运行:sudo bash -c \"\$(curl -sSL ${PPQ_BASE_URL}/install.sh)\"" exit 1 fi if [ -f /etc/os-release ]; then . /etc/os-release; OS=$ID; else OS="unknown"; fi case "$OS" in ubuntu|debian|centos|rhel|fedora|rocky|almalinux|opencloudos|anolis) ;; *) c_yellow "未识别的系统 $OS,将继续尝试安装(风险自担)";; esac ARCH=$(uname -m) case "$ARCH" in x86_64|amd64) ;; *) c_red "目前只支持 x86_64(你的机器是 $ARCH)"; exit 1;; esac MEM_MB=$(awk '/MemTotal/ {printf "%d", $2/1024}' /proc/meminfo) c_green "系统: $PRETTY_NAME | 架构: $ARCH | 内存: ${MEM_MB}MB" if [ "$MEM_MB" -lt 2048 ]; then c_yellow "内存不足 2G:基础功能可用,但不要同时装太多应用(海盘建议 4G+)" fi if ! command -v curl >/dev/null 2>&1; then step "安装 curl" if command -v apt-get >/dev/null 2>&1; then apt-get update -qq && apt-get install -y -qq curl elif command -v yum >/dev/null 2>&1; then yum install -y -q curl; fi fi # ---------- 2. 安装 Docker ---------- step "[2/8] 检查 / 安装 Docker" if ! command -v docker >/dev/null 2>&1; then c_yellow "未检测到 Docker,开始安装(约 1-3 分钟)..." curl -fsSL https://get.docker.com | bash -s -- --mirror Aliyun 2>/dev/null || curl -fsSL https://get.docker.com | bash systemctl enable --now docker 2>/dev/null || true fi docker version >/dev/null 2>&1 && c_green "Docker 就绪: $(docker --version)" || { c_red "Docker 安装失败,请检查网络"; exit 1; } # ---------- 3. 下载面板包 ---------- step "[3/8] 下载 PPQpanel v${PPQ_VERSION}" mkdir -p "$WORKDIR" PKG="$WORKDIR/ppqpanel-${PPQ_VERSION}.tar.gz" if [ ! -s "$PKG" ]; then curl -fsSL --connect-timeout 15 "${PPQ_BASE_URL}/release/ppqpanel-${PPQ_VERSION}.tar.gz" -o "$PKG" || { c_red "面板包下载失败:${PPQ_BASE_URL}/release/ppqpanel-${PPQ_VERSION}.tar.gz"; exit 1; } fi tar xzf "$PKG" -C "$WORKDIR" --strip-components=1 c_green "下载并解压完成" # ---------- 4. 安装二进制与服务 ---------- step "[4/8] 安装面板内核(官方二进制,未改动)" install -m 755 "$WORKDIR/bin/1panel-core" /usr/local/bin/1panel-core install -m 755 "$WORKDIR/bin/1panel-agent" /usr/local/bin/1panel-agent install -m 755 "$WORKDIR/bin/1pctl" /usr/local/bin/1pctl install -m 755 "$WORKDIR/bin/ppqpctl" /usr/local/bin/ppqpctl cat >/etc/systemd/system/ppqpanel-core.service <<'UNIT' [Unit] Description=PPQpanel Core After=syslog.target network-online.target Wants=network-online.target [Service] Type=simple ExecStart=/usr/local/bin/1panel-core Restart=always RestartSec=5 LimitNOFILE=1048576 [Install] WantedBy=multi-user.target UNIT cat >/etc/systemd/system/ppqpanel-agent.service <<'UNIT' [Unit] Description=PPQpanel Agent After=syslog.target network-online.target Wants=network-online.target [Service] Type=simple ExecStart=/usr/local/bin/1panel-agent Restart=always RestartSec=5 LimitNOFILE=1048576 [Install] WantedBy=multi-user.target UNIT systemctl daemon-reload systemctl enable --now ppqpanel-core ppqpanel-agent >/dev/null 2>&1 c_green "服务已启动:ppqpanel-core / ppqpanel-agent" # ---------- 5. 等待面板就绪并初始化 ---------- step "[5/8] 初始化面板" for i in $(seq 1 30); do curl -s -o /dev/null --max-time 3 "http://127.0.0.1:${PANEL_PORT}/" && break sleep 2 done ADMIN_PASS=$(head -c 12 /dev/urandom | base64 | tr -dc 'A-Za-z0-9' | head -c 16) echo "$ADMIN_PASS" > /root/.ppq_admin_pass && chmod 600 /root/.ppq_admin_pass ppqpctl update username "$ADMIN_USER" >/dev/null 2>&1 || true ppqpctl update password "$ADMIN_PASS" >/dev/null 2>&1 || true ppqpctl update entrance "$PANEL_ENTRANCE" >/dev/null 2>&1 || true ppqpctl update port "$PANEL_PORT" >/dev/null 2>&1 || true # 面板品牌名(数据层设置,官方命令覆盖不到,直接写库) if command -v python3 >/dev/null 2>&1; then python3 - </dev/null 2>&1; then sqlite3 /opt/1panel/db/core.db "insert or replace into settings(key,value) values('PanelName','PPQpanel');" fi ppqpctl restart core >/dev/null 2>&1 || systemctl restart ppqpanel-core c_green "面板初始化完成(账号 ${ADMIN_USER},密码已随机生成)" # ---------- 6. 装载自家应用 ---------- step "[6/8] 安装 PPQ 自家应用(7 个)" if [ -d "$WORKDIR/apps" ]; then mkdir -p "$LOCAL_APP_STORE" cp -rf "$WORKDIR/apps/"* "$LOCAL_APP_STORE/" c_green "应用商店已就位:$LOCAL_APP_STORE" fi # ---------- 7. 装载镜像 ---------- step "[7/8] 装载应用镜像" IMG_TGZ="$WORKDIR/${IMAGES_TGZ}" if [ -s "$IMG_TGZ" ]; then c_yellow "正在加载私有镜像(约几分钟,取决于机器性能)..." docker load -i "$IMG_TGZ" >/dev/null 2>&1 c_green "私有镜像加载完成(MySQL/Seafile 等公共镜像将在首次安装应用时自动拉取)" else c_yellow "未找到本地镜像包,将尝试从镜像仓库拉取(需要配置 registry)" fi # ---------- 8. 收尾 ---------- step "[8/8] 完成!" IP=$(hostname -I 2>/dev/null | awk '{print $1}') echo "" c_green "════════════════════════════════════════════" c_green " PPQpanel 安装完成!" c_green " 面板地址: http://${IP}:${PANEL_PORT}/${PANEL_ENTRANCE}" c_green " 用户名: ${ADMIN_USER}" c_green " 密码: ${ADMIN_PASS} ← 请立即保存并登录后修改" c_green "════════════════════════════════════════════" cat <<'NOTE' 后续建议: 1. 登录后到「设置」里开启两步验证(MFA) 2. 只放行防火墙端口:22 / 80 / 443 / 面板端口 3. 应用商店 → 本地应用,可看到 7 个 PPQ 自家应用,一键安装 4. 卸载方式:ppqpctl uninstall NOTE