install_deps.sh 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #!/usr/bin/env bash
  2. # =============================================================================
  3. # FranklinWH Toolbox - 依赖检测与安装脚本(Ubuntu)
  4. # =============================================================================
  5. # 作用:检测并(按需)安装本项目所需的数据库引擎与运行时组件:
  6. # - PostgreSQL 14+
  7. # - MongoDB 8.0
  8. # - Redis 7.x
  9. # - MinIO(对象存储)+ mc(MinIO Client)
  10. # - Docker + Docker Compose 插件(Casdoor 需要)
  11. # - Go 1.26 / Node 22 + pnpm(仅“构建”时需要,可选)
  12. #
  13. # 特点:
  14. # * 每个组件都是“先检测,缺失才安装”,可重复执行(幂等)
  15. # * 支持仅检测:DETECT_ONLY=1 ./install_deps.sh
  16. # * 可指定要处理的组件:./install_deps.sh postgres mongo redis minio docker
  17. # 不带参数时处理默认集合:postgres mongo redis minio docker mc
  18. #
  19. # 环境变量:
  20. # MINIO_API_PORT MinIO S3 API 端口 (默认 9198)
  21. # MINIO_CONSOLE_PORT MinIO 控制台端口 (默认 9199)
  22. # MINIO_ROOT_USER MinIO 管理员用户 (默认 minioadmin)
  23. # MINIO_ROOT_PASSWORD MinIO 管理员密码 (默认 minioadmin)
  24. # GO_VERSION Go 版本 (默认 1.26.4)
  25. # =============================================================================
  26. set -euo pipefail
  27. MINIO_API_PORT="${MINIO_API_PORT:-9198}"
  28. MINIO_CONSOLE_PORT="${MINIO_CONSOLE_PORT:-9199}"
  29. # TODO: [必填] MinIO 管理员账户——请通过环境变量传入强口令,勿使用默认 minioadmin/minioadmin
  30. MINIO_ROOT_USER="${MINIO_ROOT_USER:-minioadmin}"
  31. MINIO_ROOT_PASSWORD="${MINIO_ROOT_PASSWORD:-minioadmin}"
  32. # TODO: [确认] Go 版本(仅在需要安装 Go 时用到)
  33. GO_VERSION="${GO_VERSION:-1.26.4}"
  34. DETECT_ONLY="${DETECT_ONLY:-0}"
  35. c_reset='\033[0m'; c_blue='\033[1;34m'; c_green='\033[1;32m'; c_yellow='\033[1;33m'; c_red='\033[1;31m'
  36. info() { echo -e "${c_blue}[INFO]${c_reset} $*"; }
  37. ok() { echo -e "${c_green}[ OK ]${c_reset} $*"; }
  38. warn() { echo -e "${c_yellow}[WARN]${c_reset} $*"; }
  39. err() { echo -e "${c_red}[FAIL]${c_reset} $*" >&2; }
  40. has() { command -v "$1" >/dev/null 2>&1; }
  41. # 仅检测时的统一处理:打印状态并返回,跳过安装
  42. _detect_guard() {
  43. # $1=组件名 $2=已安装(0/1) $3=版本串
  44. if [[ "$2" == "1" ]]; then
  45. ok "$1 已安装:$3"
  46. return 0 # 已装 -> 调用方 return
  47. fi
  48. if [[ "${DETECT_ONLY}" == "1" ]]; then
  49. warn "$1 未安装(仅检测模式,跳过安装)"
  50. return 0
  51. fi
  52. return 1 # 未装且需要安装 -> 调用方继续执行安装
  53. }
  54. apt_update_once() {
  55. if [[ -z "${_APT_UPDATED:-}" ]]; then
  56. sudo apt-get update -y
  57. _APT_UPDATED=1
  58. fi
  59. }
  60. # ---------------------------------------------------------------------------
  61. # PostgreSQL
  62. # ---------------------------------------------------------------------------
  63. ensure_postgres() {
  64. local ver=""
  65. has psql && ver="$(psql --version 2>/dev/null | awk '{print $3}')"
  66. _detect_guard "PostgreSQL" "$([[ -n $ver ]] && echo 1 || echo 0)" "${ver}" && return 0
  67. info "安装 PostgreSQL ..."
  68. apt_update_once
  69. sudo apt-get install -y postgresql postgresql-contrib
  70. sudo systemctl enable --now postgresql
  71. ok "PostgreSQL 安装完成:$(psql --version | awk '{print $3}')"
  72. }
  73. # ---------------------------------------------------------------------------
  74. # MongoDB 8.0
  75. # ---------------------------------------------------------------------------
  76. ensure_mongo() {
  77. local ver=""
  78. has mongod && ver="$(mongod --version 2>/dev/null | awk 'NR==1{print $3}')"
  79. _detect_guard "MongoDB" "$([[ -n $ver ]] && echo 1 || echo 0)" "${ver}" && return 0
  80. info "安装 MongoDB 8.0 ..."
  81. local codename; codename="$(. /etc/os-release && echo "${VERSION_CODENAME:-jammy}")"
  82. curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc \
  83. | sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg --dearmor --yes
  84. 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" \
  85. | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list >/dev/null
  86. sudo apt-get update -y
  87. sudo apt-get install -y mongodb-org
  88. sudo systemctl enable --now mongod
  89. ok "MongoDB 安装完成"
  90. }
  91. # ---------------------------------------------------------------------------
  92. # Redis
  93. # ---------------------------------------------------------------------------
  94. ensure_redis() {
  95. local ver=""
  96. has redis-server && ver="$(redis-server --version 2>/dev/null | sed -E 's/.*v=([0-9.]+).*/\1/')"
  97. _detect_guard "Redis" "$([[ -n $ver ]] && echo 1 || echo 0)" "${ver}" && return 0
  98. info "安装 Redis ..."
  99. apt_update_once
  100. sudo apt-get install -y redis-server
  101. sudo systemctl enable --now redis-server
  102. ok "Redis 安装完成"
  103. }
  104. # ---------------------------------------------------------------------------
  105. # MinIO + mc
  106. # ---------------------------------------------------------------------------
  107. ensure_minio() {
  108. local ver=""
  109. has minio && ver="installed"
  110. if _detect_guard "MinIO" "$([[ -n $ver ]] && echo 1 || echo 0)" "$(command -v minio || true)"; then
  111. return 0
  112. fi
  113. info "安装 MinIO(二进制 + systemd)..."
  114. sudo wget -q -O /usr/local/bin/minio https://dl.min.io/server/minio/release/linux-amd64/minio
  115. sudo chmod +x /usr/local/bin/minio
  116. id minio-user >/dev/null 2>&1 || sudo useradd -r minio-user -s /sbin/nologin
  117. sudo mkdir -p /var/lib/minio/data
  118. sudo chown -R minio-user:minio-user /var/lib/minio
  119. sudo tee /etc/default/minio >/dev/null <<EOF
  120. MINIO_VOLUMES="/var/lib/minio/data"
  121. MINIO_OPTS="--address :${MINIO_API_PORT} --console-address :${MINIO_CONSOLE_PORT}"
  122. MINIO_ROOT_USER="${MINIO_ROOT_USER}"
  123. MINIO_ROOT_PASSWORD="${MINIO_ROOT_PASSWORD}"
  124. EOF
  125. sudo tee /etc/systemd/system/minio.service >/dev/null <<'EOF'
  126. [Unit]
  127. Description=MinIO
  128. Documentation=https://docs.min.io
  129. Wants=network-online.target
  130. After=network-online.target
  131. AssertFileIsExecutable=/usr/local/bin/minio
  132. [Service]
  133. Type=notify
  134. WorkingDirectory=/usr/local
  135. User=minio-user
  136. Group=minio-user
  137. EnvironmentFile=-/etc/default/minio
  138. ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
  139. Restart=always
  140. LimitNOFILE=1048576
  141. TasksMax=infinity
  142. OOMScoreAdjust=-1000
  143. [Install]
  144. WantedBy=multi-user.target
  145. EOF
  146. sudo systemctl daemon-reload
  147. sudo systemctl enable --now minio
  148. ok "MinIO 安装完成(API :${MINIO_API_PORT} / 控制台 :${MINIO_CONSOLE_PORT})"
  149. }
  150. ensure_mc() {
  151. local ver=""
  152. has mc && ver="installed"
  153. _detect_guard "mc(MinIO Client)" "$([[ -n $ver ]] && echo 1 || echo 0)" "$(command -v mc || true)" && return 0
  154. info "安装 mc(MinIO Client)..."
  155. sudo wget -q -O /usr/local/bin/mc https://dl.min.io/client/mc/release/linux-amd64/mc
  156. sudo chmod +x /usr/local/bin/mc
  157. ok "mc 安装完成"
  158. }
  159. # ---------------------------------------------------------------------------
  160. # Docker + Compose 插件(Casdoor 需要)
  161. # ---------------------------------------------------------------------------
  162. ensure_docker() {
  163. local ver=""
  164. has docker && ver="$(docker --version 2>/dev/null | awk '{print $3}' | tr -d ,)"
  165. _detect_guard "Docker" "$([[ -n $ver ]] && echo 1 || echo 0)" "${ver}" && return 0
  166. info "安装 Docker CE + compose 插件 ..."
  167. apt_update_once
  168. sudo apt-get install -y ca-certificates curl gnupg
  169. sudo install -m 0755 -d /etc/apt/keyrings
  170. curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  171. | sudo gpg --dearmor --yes -o /etc/apt/keyrings/docker.gpg
  172. sudo chmod a+r /etc/apt/keyrings/docker.gpg
  173. local codename; codename="$(. /etc/os-release && echo "${VERSION_CODENAME:-jammy}")"
  174. echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu ${codename} stable" \
  175. | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
  176. sudo apt-get update -y
  177. sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  178. sudo systemctl enable --now docker
  179. ok "Docker 安装完成:$(docker --version)"
  180. }
  181. # ---------------------------------------------------------------------------
  182. # Go / Node(仅构建时需要)
  183. # ---------------------------------------------------------------------------
  184. ensure_go() {
  185. local ver=""
  186. has go && ver="$(go version 2>/dev/null | awk '{print $3}')"
  187. _detect_guard "Go" "$([[ -n $ver ]] && echo 1 || echo 0)" "${ver}" && return 0
  188. info "安装 Go ${GO_VERSION} ..."
  189. wget -q "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" -O /tmp/go.tgz
  190. sudo rm -rf /usr/local/go
  191. sudo tar -C /usr/local -xzf /tmp/go.tgz
  192. rm -f /tmp/go.tgz
  193. echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee /etc/profile.d/go.sh >/dev/null
  194. export PATH="$PATH:/usr/local/go/bin"
  195. ok "Go 安装完成:$(go version | awk '{print $3}')"
  196. }
  197. ensure_node() {
  198. local ver=""
  199. has node && ver="$(node -v 2>/dev/null)"
  200. _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; }
  201. info "安装 Node.js 22 + pnpm ..."
  202. curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
  203. sudo apt-get install -y nodejs
  204. sudo npm install -g pnpm@8
  205. ok "Node/pnpm 安装完成:$(node -v) / pnpm $(pnpm -v)"
  206. }
  207. # ---------------------------------------------------------------------------
  208. # 主流程
  209. # ---------------------------------------------------------------------------
  210. main() {
  211. local comps=("$@")
  212. [[ ${#comps[@]} -eq 0 ]] && comps=(postgres mongo redis minio mc docker)
  213. [[ "${DETECT_ONLY}" == "1" ]] && info "== 仅检测模式 ==" || info "== 检测并安装缺失组件 =="
  214. for c in "${comps[@]}"; do
  215. case "${c}" in
  216. postgres|pg) ensure_postgres ;;
  217. mongo|mongodb) ensure_mongo ;;
  218. redis) ensure_redis ;;
  219. minio) ensure_minio ;;
  220. mc) ensure_mc ;;
  221. docker) ensure_docker ;;
  222. go) ensure_go ;;
  223. node) ensure_node ;;
  224. *) warn "未知组件:${c}(可选:postgres mongo redis minio mc docker go node)" ;;
  225. esac
  226. done
  227. ok "依赖处理完成"
  228. }
  229. main "$@"