install_pgadmin.sh 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #!/usr/bin/env bash
  2. # =============================================================================
  3. # FranklinWH Toolbox - pgAdmin4(Web)部署脚本
  4. # =============================================================================
  5. # 作用:
  6. # 1. 给现有 PostgreSQL 超级用户 postgres 设置登录密码(供 pgAdmin 连接用)
  7. # 2. 以 Docker Compose 部署 Web 版 pgAdmin4(dpage/pgadmin4)
  8. # 3. 检测 pg_hba.conf / listen_addresses,打印让容器经 TCP 连本机 PG 所需的配置
  9. # (本脚本【不】自动修改系统配置文件,仅给出提示,改动交由你确认执行)
  10. #
  11. # 前置条件:
  12. # - Docker + docker compose 插件已安装(可用 install_deps.sh docker)
  13. # - PostgreSQL 已安装并运行(本机 :5432),且当前用户可 sudo -u postgres psql
  14. #
  15. # 用法:
  16. # POSTGRES_PASSWORD='强密码' PGADMIN_PASSWORD='强密码' ./install_pgadmin.sh
  17. #
  18. # 可用环境变量(均有默认值):
  19. # POSTGRES_PASSWORD PostgreSQL 超级用户 postgres 的新密码 (默认 change_me_strong)
  20. # PGADMIN_EMAIL pgAdmin4 Web 登录邮箱 (默认 liang_jlyx@163.com)
  21. # PGADMIN_PASSWORD pgAdmin4 Web 登录密码 (默认 change_me_strong)
  22. # PGADMIN_PORT pgAdmin4 对外端口 (默认 5480)
  23. # PGADMIN_BIND 端口绑定地址(默认仅本机,防公网暴露) (默认 127.0.0.1)
  24. # PGADMIN_DIR pgAdmin 部署目录 (默认 /home/$USER/docker/pgadmin)
  25. # PG_HOST 容器视角的 PG 主机 (默认 host.docker.internal)
  26. # PG_PORT PG 端口 (默认 5432)
  27. # =============================================================================
  28. set -euo pipefail
  29. # TODO: [必填] postgres 超级用户新密码——请通过环境变量传入强口令,勿用默认
  30. POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-change_me_strong}"
  31. PGADMIN_EMAIL="${PGADMIN_EMAIL:-liang_jlyx@163.com}"
  32. # TODO: [必填] pgAdmin4 Web 登录密码——请通过环境变量传入强口令,勿用默认
  33. PGADMIN_PASSWORD="${PGADMIN_PASSWORD:-change_me_strong}"
  34. PGADMIN_PORT="${PGADMIN_PORT:-5480}"
  35. PGADMIN_BIND="${PGADMIN_BIND:-127.0.0.1}"
  36. PGADMIN_DIR="${PGADMIN_DIR:-$HOME/docker/pgadmin}"
  37. PG_HOST="${PG_HOST:-host.docker.internal}"
  38. PG_PORT="${PG_PORT:-5432}"
  39. c_reset='\033[0m'; c_blue='\033[1;34m'; c_green='\033[1;32m'; c_yellow='\033[1;33m'; c_red='\033[1;31m'
  40. info() { echo -e "${c_blue}[INFO]${c_reset} $*"; }
  41. ok() { echo -e "${c_green}[ OK ]${c_reset} $*"; }
  42. warn() { echo -e "${c_yellow}[WARN]${c_reset} $*"; }
  43. err() { echo -e "${c_red}[FAIL]${c_reset} $*" >&2; }
  44. # docker compose 命令探测(插件 or 独立二进制)
  45. compose() {
  46. if docker compose version >/dev/null 2>&1; then
  47. docker compose "$@"
  48. elif command -v docker-compose >/dev/null 2>&1; then
  49. docker-compose "$@"
  50. else
  51. err "未找到 docker compose,请先安装(install_deps.sh docker)"; return 1
  52. fi
  53. }
  54. # ---------------------------------------------------------------------------
  55. # 1. 给 postgres 超级用户设置密码
  56. # 使用 psql 变量 + %L 转义,安全支持含特殊字符的密码。
  57. # ---------------------------------------------------------------------------
  58. set_postgres_password() {
  59. info "为 PostgreSQL 超级用户 postgres 设置密码 ..."
  60. command -v psql >/dev/null 2>&1 || { err "未找到 psql,请先安装 PostgreSQL"; return 1; }
  61. if [[ "${POSTGRES_PASSWORD}" == "change_me_strong" ]]; then
  62. warn "当前使用默认占位密码 change_me_strong,请务必改用强口令后重跑:"
  63. warn " POSTGRES_PASSWORD='你的强口令' ./install_pgadmin.sh"
  64. fi
  65. sudo -u postgres psql -v ON_ERROR_STOP=1 -v pwd="${POSTGRES_PASSWORD}" <<'SQL'
  66. SELECT format('ALTER ROLE postgres WITH PASSWORD %L', :'pwd')
  67. \gexec
  68. SQL
  69. ok "postgres 密码已设置"
  70. }
  71. # ---------------------------------------------------------------------------
  72. # 2. 检测 pg_hba.conf / listen_addresses(只提示,不自动改)
  73. # ---------------------------------------------------------------------------
  74. check_pg_network() {
  75. info "检查 PostgreSQL 是否允许容器经 TCP 连接(密码认证)..."
  76. local hba conf listen
  77. hba="$(sudo -u postgres psql -tAc 'SHOW hba_file;' 2>/dev/null || true)"
  78. conf="$(sudo -u postgres psql -tAc 'SHOW config_file;' 2>/dev/null || true)"
  79. listen="$(sudo -u postgres psql -tAc 'SHOW listen_addresses;' 2>/dev/null || true)"
  80. info " hba_file : ${hba:-未知}"
  81. info " config_file : ${conf:-未知}"
  82. info " listen_addresses: ${listen:-未知}"
  83. if [[ "${listen}" != "*" && "${listen}" != *"0.0.0.0"* ]]; then
  84. warn "listen_addresses 当前为 '${listen}',容器可能无法经 host-gateway 连入。"
  85. warn "如需允许,请在 ${conf:-postgresql.conf} 设置: listen_addresses = '*'"
  86. fi
  87. cat <<EOF
  88. ${c_yellow}[WARN]${c_reset} 若要用 postgres + 密码从 pgAdmin 容器连入,请确认 ${hba:-pg_hba.conf} 中
  89. 有一条允许 Docker 网段、且认证方式为 scram-sha-256 的 host 记录,例如:
  90. # 允许 Docker 默认网段以密码方式连接(按需收窄网段)
  91. host all all 172.16.0.0/12 scram-sha-256
  92. 修改后执行: sudo systemctl reload postgresql
  93. (本脚本不会自动修改系统配置文件。)
  94. EOF
  95. }
  96. # ---------------------------------------------------------------------------
  97. # 3. 生成 compose 并启动 pgAdmin4
  98. # ---------------------------------------------------------------------------
  99. deploy_pgadmin() {
  100. info "生成 pgAdmin4 部署文件到 ${PGADMIN_DIR} ..."
  101. mkdir -p "${PGADMIN_DIR}"
  102. if [[ "${PGADMIN_PASSWORD}" == "change_me_strong" ]]; then
  103. warn "pgAdmin 登录密码为默认占位 change_me_strong,请改用强口令:"
  104. warn " PGADMIN_PASSWORD='你的强口令' ./install_pgadmin.sh"
  105. fi
  106. cat > "${PGADMIN_DIR}/docker-compose.yml" <<EOF
  107. services:
  108. pgadmin:
  109. image: dpage/pgadmin4:latest
  110. restart: always
  111. ports:
  112. # 默认仅绑定本机,避免公网直接暴露;如需内网访问改 PGADMIN_BIND
  113. - "${PGADMIN_BIND}:${PGADMIN_PORT}:80"
  114. environment:
  115. PGADMIN_DEFAULT_EMAIL: "${PGADMIN_EMAIL}"
  116. PGADMIN_DEFAULT_PASSWORD: "${PGADMIN_PASSWORD}"
  117. # 关闭主密码,简化单人使用;多人共享请置为 True
  118. PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: "False"
  119. extra_hosts:
  120. - "host.docker.internal:host-gateway"
  121. volumes:
  122. - pgadmin_data:/var/lib/pgadmin
  123. volumes:
  124. pgadmin_data:
  125. EOF
  126. ok "已生成 docker-compose.yml"
  127. info "启动 pgAdmin4 容器 ..."
  128. ( cd "${PGADMIN_DIR}" && compose up -d )
  129. sleep 2
  130. ( cd "${PGADMIN_DIR}" && compose ps )
  131. ok "pgAdmin4 已启动"
  132. }
  133. main() {
  134. info "== 部署 pgAdmin4(Web)+ 设置 postgres 密码 =="
  135. command -v docker >/dev/null 2>&1 || { err "未找到 docker,请先安装(install_deps.sh docker)"; exit 1; }
  136. set_postgres_password
  137. check_pg_network
  138. deploy_pgadmin
  139. cat <<EOF
  140. ${c_green}pgAdmin4 部署完成${c_reset}
  141. 部署目录 : ${PGADMIN_DIR}
  142. 访问地址 : http://${PGADMIN_BIND}:${PGADMIN_PORT}
  143. 登录邮箱 : ${PGADMIN_EMAIL}
  144. 登录密码 : (见环境变量 PGADMIN_PASSWORD)
  145. 在 pgAdmin 里新建 Server 连接本机 PostgreSQL:
  146. Host name/address : ${PG_HOST} # 容器视角,经 host-gateway 连宿主机
  147. Port : ${PG_PORT}
  148. Username : postgres
  149. Password : (见环境变量 POSTGRES_PASSWORD)
  150. ${c_yellow}安全提示${c_reset}:
  151. - postgres 是超级用户,切勿把 ${PGADMIN_PORT} 端口直接暴露到公网;
  152. 建议置于反向代理(如 Caddy) + 访问控制之后(参考 install_caddy.sh)。
  153. - 若连接报认证失败,多为 pg_hba.conf 未启用 scram-sha-256,见上文提示。
  154. EOF
  155. }
  156. main "$@"