145 lines
4.8 KiB
Bash
145 lines
4.8 KiB
Bash
|
|
#!/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 # 进容器调试"
|