#!/usr/bin/env bash # ============================================================================= # FranklinWH Toolbox - 依赖检测与安装脚本(Ubuntu) # ============================================================================= # 作用:检测并(按需)安装本项目所需的数据库引擎与运行时组件: # - PostgreSQL 14+ # - MongoDB 8.0 # - Redis 7.x # - MinIO(对象存储)+ mc(MinIO Client) # - Docker + Docker Compose 插件(Casdoor 需要) # - Go 1.26 / Node 22 + pnpm(仅“构建”时需要,可选) # # 特点: # * 每个组件都是“先检测,缺失才安装”,可重复执行(幂等) # * 支持仅检测:DETECT_ONLY=1 ./install_deps.sh # * 可指定要处理的组件:./install_deps.sh postgres mongo redis minio docker # 不带参数时处理默认集合:postgres mongo redis minio docker mc # # 环境变量: # MINIO_API_PORT MinIO S3 API 端口 (默认 9198) # MINIO_CONSOLE_PORT MinIO 控制台端口 (默认 9199) # MINIO_ROOT_USER MinIO 管理员用户 (默认 minioadmin) # MINIO_ROOT_PASSWORD MinIO 管理员密码 (默认 minioadmin) # GO_VERSION Go 版本 (默认 1.26.4) # ============================================================================= set -euo pipefail MINIO_API_PORT="${MINIO_API_PORT:-9198}" MINIO_CONSOLE_PORT="${MINIO_CONSOLE_PORT:-9199}" # TODO: [必填] MinIO 管理员账户——请通过环境变量传入强口令,勿使用默认 minioadmin/minioadmin MINIO_ROOT_USER="${MINIO_ROOT_USER:-minioadmin}" MINIO_ROOT_PASSWORD="${MINIO_ROOT_PASSWORD:-minioadmin}" # TODO: [确认] Go 版本(仅在需要安装 Go 时用到) GO_VERSION="${GO_VERSION:-1.26.4}" DETECT_ONLY="${DETECT_ONLY:-0}" c_reset='\033[0m'; c_blue='\033[1;34m'; c_green='\033[1;32m'; c_yellow='\033[1;33m'; c_red='\033[1;31m' info() { echo -e "${c_blue}[INFO]${c_reset} $*"; } ok() { echo -e "${c_green}[ OK ]${c_reset} $*"; } warn() { echo -e "${c_yellow}[WARN]${c_reset} $*"; } err() { echo -e "${c_red}[FAIL]${c_reset} $*" >&2; } has() { command -v "$1" >/dev/null 2>&1; } # 仅检测时的统一处理:打印状态并返回,跳过安装 _detect_guard() { # $1=组件名 $2=已安装(0/1) $3=版本串 if [[ "$2" == "1" ]]; then ok "$1 已安装:$3" return 0 # 已装 -> 调用方 return fi if [[ "${DETECT_ONLY}" == "1" ]]; then warn "$1 未安装(仅检测模式,跳过安装)" return 0 fi return 1 # 未装且需要安装 -> 调用方继续执行安装 } apt_update_once() { if [[ -z "${_APT_UPDATED:-}" ]]; then sudo apt-get update -y _APT_UPDATED=1 fi } # --------------------------------------------------------------------------- # PostgreSQL # --------------------------------------------------------------------------- ensure_postgres() { local ver="" has psql && ver="$(psql --version 2>/dev/null | awk '{print $3}')" _detect_guard "PostgreSQL" "$([[ -n $ver ]] && echo 1 || echo 0)" "${ver}" && return 0 info "安装 PostgreSQL ..." apt_update_once sudo apt-get install -y postgresql postgresql-contrib sudo systemctl enable --now postgresql ok "PostgreSQL 安装完成:$(psql --version | awk '{print $3}')" } # --------------------------------------------------------------------------- # MongoDB 8.0 # --------------------------------------------------------------------------- ensure_mongo() { local ver="" has mongod && ver="$(mongod --version 2>/dev/null | awk 'NR==1{print $3}')" _detect_guard "MongoDB" "$([[ -n $ver ]] && echo 1 || echo 0)" "${ver}" && return 0 info "安装 MongoDB 8.0 ..." local codename; codename="$(. /etc/os-release && echo "${VERSION_CODENAME:-jammy}")" curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc \ | sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg --dearmor --yes echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] https://repo.mongodb.org/apt/ubuntu ${codename}/mongodb-org/8.0 multiverse" \ | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list >/dev/null sudo apt-get update -y sudo apt-get install -y mongodb-org sudo systemctl enable --now mongod ok "MongoDB 安装完成" } # --------------------------------------------------------------------------- # Redis # --------------------------------------------------------------------------- ensure_redis() { local ver="" has redis-server && ver="$(redis-server --version 2>/dev/null | sed -E 's/.*v=([0-9.]+).*/\1/')" _detect_guard "Redis" "$([[ -n $ver ]] && echo 1 || echo 0)" "${ver}" && return 0 info "安装 Redis ..." apt_update_once sudo apt-get install -y redis-server sudo systemctl enable --now redis-server ok "Redis 安装完成" } # --------------------------------------------------------------------------- # MinIO + mc # --------------------------------------------------------------------------- ensure_minio() { local ver="" has minio && ver="installed" if _detect_guard "MinIO" "$([[ -n $ver ]] && echo 1 || echo 0)" "$(command -v minio || true)"; then return 0 fi info "安装 MinIO(二进制 + systemd)..." sudo wget -q -O /usr/local/bin/minio https://dl.min.io/server/minio/release/linux-amd64/minio sudo chmod +x /usr/local/bin/minio id minio-user >/dev/null 2>&1 || sudo useradd -r minio-user -s /sbin/nologin sudo mkdir -p /var/lib/minio/data sudo chown -R minio-user:minio-user /var/lib/minio sudo tee /etc/default/minio >/dev/null </dev/null <<'EOF' [Unit] Description=MinIO Documentation=https://docs.min.io Wants=network-online.target After=network-online.target AssertFileIsExecutable=/usr/local/bin/minio [Service] Type=notify WorkingDirectory=/usr/local User=minio-user Group=minio-user EnvironmentFile=-/etc/default/minio ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES Restart=always LimitNOFILE=1048576 TasksMax=infinity OOMScoreAdjust=-1000 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable --now minio ok "MinIO 安装完成(API :${MINIO_API_PORT} / 控制台 :${MINIO_CONSOLE_PORT})" } ensure_mc() { local ver="" has mc && ver="installed" _detect_guard "mc(MinIO Client)" "$([[ -n $ver ]] && echo 1 || echo 0)" "$(command -v mc || true)" && return 0 info "安装 mc(MinIO Client)..." sudo wget -q -O /usr/local/bin/mc https://dl.min.io/client/mc/release/linux-amd64/mc sudo chmod +x /usr/local/bin/mc ok "mc 安装完成" } # --------------------------------------------------------------------------- # Docker + Compose 插件(Casdoor 需要) # --------------------------------------------------------------------------- ensure_docker() { local ver="" has docker && ver="$(docker --version 2>/dev/null | awk '{print $3}' | tr -d ,)" _detect_guard "Docker" "$([[ -n $ver ]] && echo 1 || echo 0)" "${ver}" && return 0 info "安装 Docker CE + compose 插件 ..." apt_update_once sudo apt-get install -y ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg \ | sudo gpg --dearmor --yes -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg local codename; codename="$(. /etc/os-release && echo "${VERSION_CODENAME:-jammy}")" echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu ${codename} stable" \ | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null sudo apt-get update -y sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo systemctl enable --now docker ok "Docker 安装完成:$(docker --version)" } # --------------------------------------------------------------------------- # Go / Node(仅构建时需要) # --------------------------------------------------------------------------- ensure_go() { local ver="" has go && ver="$(go version 2>/dev/null | awk '{print $3}')" _detect_guard "Go" "$([[ -n $ver ]] && echo 1 || echo 0)" "${ver}" && return 0 info "安装 Go ${GO_VERSION} ..." wget -q "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" -O /tmp/go.tgz sudo rm -rf /usr/local/go sudo tar -C /usr/local -xzf /tmp/go.tgz rm -f /tmp/go.tgz echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee /etc/profile.d/go.sh >/dev/null export PATH="$PATH:/usr/local/go/bin" ok "Go 安装完成:$(go version | awk '{print $3}')" } ensure_node() { local ver="" has node && ver="$(node -v 2>/dev/null)" _detect_guard "Node.js" "$([[ -n $ver ]] && echo 1 || echo 0)" "${ver}" && { has pnpm || { [[ ${DETECT_ONLY} == 1 ]] || { sudo npm install -g pnpm@8; ok "pnpm 安装完成"; }; }; return 0; } info "安装 Node.js 22 + pnpm ..." curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - sudo apt-get install -y nodejs sudo npm install -g pnpm@8 ok "Node/pnpm 安装完成:$(node -v) / pnpm $(pnpm -v)" } # --------------------------------------------------------------------------- # 主流程 # --------------------------------------------------------------------------- main() { local comps=("$@") [[ ${#comps[@]} -eq 0 ]] && comps=(postgres mongo redis minio mc docker) [[ "${DETECT_ONLY}" == "1" ]] && info "== 仅检测模式 ==" || info "== 检测并安装缺失组件 ==" for c in "${comps[@]}"; do case "${c}" in postgres|pg) ensure_postgres ;; mongo|mongodb) ensure_mongo ;; redis) ensure_redis ;; minio) ensure_minio ;; mc) ensure_mc ;; docker) ensure_docker ;; go) ensure_go ;; node) ensure_node ;; *) warn "未知组件:${c}(可选:postgres mongo redis minio mc docker go node)" ;; esac done ok "依赖处理完成" } main "$@"