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 # 进容器调试"
|