#!/usr/bin/env bash # datahub 一键部署脚本(阶段 3-7) # # 假设阶段 0-2 已完成:podman 已装 / subuid 已配 / lingering 已开 / 代码已 clone # # 用法:bash deploy/podman/scripts/install.sh # # 本脚本是幂等的:可重复运行;已存在的资源会跳过或询问。 set -euo pipefail # ---------- 输出辅助 ---------- B='\033[34m'; G='\033[32m'; Y='\033[33m'; R='\033[31m'; N='\033[0m' step() { echo -e "\n${B}==> [$1/5] $2${N}"; } ok() { echo -e "${G}[OK]${N} $*"; } warn() { echo -e "${Y}[!]${N} $*"; } err() { echo -e "${R}[ERR]${N} $*" >&2; } SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) REPO_ROOT=$(cd "$SCRIPT_DIR/../../.." && pwd) QUADLET_DIR="$HOME/.config/containers/systemd" # ---------- 前置检查 ---------- echo -e "${B}=== datahub 部署脚本 ===${N}" echo "工作目录: $REPO_ROOT" echo # 调用体检脚本;MISS 不为 0 时退出码 1 → 整个安装流程中止 if ! bash "$SCRIPT_DIR/check-prereqs.sh"; then err "环境体检未通过,请按上面提示处理后重试" exit 1 fi echo # ---------- 1. 数据目录 ---------- step 1 "创建数据目录" bash "$SCRIPT_DIR/setup-data-dirs.sh" # ---------- 2. env 文件 ---------- step 2 "生成 env 文件(交互)" bash "$SCRIPT_DIR/configure-env.sh" # ---------- 3. secrets ---------- step 3 "创建 podman secrets(交互)" bash "$SCRIPT_DIR/create-secrets.sh" # ---------- 4. 构建镜像 ---------- step 4 "构建 3 个镜像" cd "$REPO_ROOT" echo -e "${B} -> datahub-postgres${N}" podman build -t localhost/datahub-postgres:latest \ -f deploy/podman/images/postgres/Dockerfile . echo -e "${B} -> datahub-backend${N}" podman build -t localhost/datahub-backend:latest \ -f backend/Dockerfile backend/ echo -e "${B} -> datahub-frontend${N}" podman build -t localhost/datahub-frontend:latest \ -f deploy/podman/images/frontend/Dockerfile . ok "镜像构建完成" podman images --format " {{.Repository}}:{{.Tag}} ({{.Size}})" | grep "^ localhost/datahub-" || true # ---------- 5. Quadlet + 启动 ---------- step 5 "部署 Quadlet 单元并启动服务" mkdir -p "$QUADLET_DIR" cp "$REPO_ROOT"/deploy/podman/quadlet/* "$QUADLET_DIR/" ok "Quadlet 单元已复制到 $QUADLET_DIR" systemctl --user daemon-reload # 等待容器达到 healthy(仅对配置了 healthcheck 的容器) wait_healthy() { local container=$1 local timeout=${2:-90} local elapsed=0 while (( elapsed < timeout )); do local status status=$(podman inspect --format '{{.State.Health.Status}}' "$container" 2>/dev/null || echo "starting") if [[ "$status" == "healthy" ]]; then ok " $container healthy(${elapsed}s)" return 0 fi sleep 3 elapsed=$((elapsed + 3)) printf "." done echo err "$container 在 ${timeout}s 内未达到 healthy" return 1 } # 启动顺序:PG → MQ → Backend → Frontend echo -e "${B} 启动 datahub-postgres...${N}" systemctl --user start datahub-postgres.service wait_healthy datahub-postgres 90 || { journalctl --user -u datahub-postgres.service -n 50 --no-pager; exit 1; } echo -e "${B} 启动 datahub-rabbitmq...${N}" systemctl --user start datahub-rabbitmq.service wait_healthy datahub-rabbitmq 90 || { journalctl --user -u datahub-rabbitmq.service -n 50 --no-pager; exit 1; } echo -e "${B} 启动 datahub-backend...${N}" systemctl --user start datahub-backend.service sleep 5 if ! systemctl --user is-active --quiet datahub-backend.service; then err "datahub-backend 未运行" journalctl --user -u datahub-backend.service -n 50 --no-pager exit 1 fi ok " datahub-backend 已运行" echo -e "${B} 启动 datahub-frontend...${N}" systemctl --user start datahub-frontend.service sleep 3 if ! systemctl --user is-active --quiet datahub-frontend.service; then err "datahub-frontend 未运行" journalctl --user -u datahub-frontend.service -n 50 --no-pager exit 1 fi ok " datahub-frontend 已运行" # ---------- 完成 ---------- HOST_IP=$(hostname -I 2>/dev/null | awk '{print $1}') echo echo -e "${G}========================================${N}" echo -e "${G} 部署完成!${N}" echo -e "${G}========================================${N}" echo echo "服务访问:" echo " 前端: http://${HOST_IP:-localhost}:8080" echo " 后端: http://${HOST_IP:-localhost}:9501" echo " RabbitMQ 控制台: http://${HOST_IP:-localhost}:15672 (账号 user)" echo echo "下一步(首次部署必做):" echo -e " ${Y}podman exec -it datahub-backend php bin/hyperf.php migrate${N}" echo echo "常用命令:" echo " podman ps # 看容器状态" echo " systemctl --user status datahub-backend # 看服务状态" echo " journalctl --user -u datahub-backend -f # 看实时日志" echo " podman exec -it datahub-backend sh # 进容器调试"