Files
lab/scripts/podman-deploy.sh
2026-09-21 13:17:14 +08:00

104 lines
3.5 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# =====================================================================
# 使用 Podman 部署实验室预约平台
#
# 用法:
# ./scripts/podman-deploy.sh up # 构建镜像并启动(默认)
# ./scripts/podman-deploy.sh down # 停止并删除容器(保留数据库数据卷)
# ./scripts/podman-deploy.sh down-v # 停止并删除容器与数据卷(重建演示数据)
# ./scripts/podman-deploy.sh status # 查看容器状态
# ./scripts/podman-deploy.sh logs # 跟随查看日志
#
# 说明:Podman 的 compose 实现(podman-compose)在容器名/镜像名解析上与
# Docker Compose 存在差异,常见报错为:
# Error: short-name "lab-reservation_backend" did not resolve to an alias ...
# 因此本脚本先显式构建 lab-backend:latest / lab-frontend:latest,
# 再交给 compose 启动,确保 compose 直接使用本地镜像而不会尝试拉取。
# =====================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
cd "${PROJECT_DIR}"
# ---------- 选择可用的 compose 命令 ----------
if podman compose version >/dev/null 2>&1; then
COMPOSE=(podman compose)
elif command -v podman-compose >/dev/null 2>&1; then
COMPOSE=(podman-compose)
else
echo "错误:未找到 podman compose / podman-compose,请先安装其一" >&2
exit 1
fi
# ---------- 读取 .env 中的端口配置(不 source,避免值中含空格被当作命令执行) ----------
read_env() {
[ -f .env ] && grep -E "^$1=" .env 2>/dev/null | tail -n 1 | cut -d= -f2- | tr -d '"' || true
}
WEB_PORT="${WEB_PORT:-$(read_env WEB_PORT)}"
BACKEND_PORT="${BACKEND_PORT:-$(read_env BACKEND_PORT)}"
WEB_PORT="${WEB_PORT:-8088}"
BACKEND_PORT="${BACKEND_PORT:-8080}"
# ---------- 构建镜像 ----------
build_images() {
echo "==> 构建后端镜像 lab-backend:latest(首次构建需拉取 Maven 依赖)"
podman build -t lab-backend:latest .
echo "==> 构建前端镜像 lab-frontend:latest"
podman build -t lab-frontend:latest ./frontend
}
# ---------- 等待 HTTP 服务就绪 ----------
wait_ready() {
local name="$1" url="$2" tries=60 code
for _ in $(seq 1 "${tries}"); do
code="$(curl -s -o /dev/null -w '%{http_code}' "${url}" || true)"
if [ -n "${code}" ] && [ "${code}" != "000" ]; then
echo " ${name} 就绪:${url}(HTTP ${code})"
return 0
fi
sleep 2
done
echo " 警告:${name} 未在预期时间内就绪,请执行 '$0 logs' 查看日志" >&2
return 1
}
ACTION="${1:-up}"
case "${ACTION}" in
up)
build_images
echo "==> 启动容器"
"${COMPOSE[@]}" up -d
echo "==> 等待服务就绪"
# 后端返回 401 也代表进程已起来
wait_ready "后端" "http://localhost:${BACKEND_PORT}/api/labs" || true
wait_ready "前端" "http://localhost:${WEB_PORT}/" || true
echo
echo "部署完成:"
echo " 前端地址:http://localhost:${WEB_PORT}"
echo " 后端地址:http://localhost:${BACKEND_PORT}"
echo " 演示账号:admin/admin123、teacher1/123456、student1/123456"
echo
"${COMPOSE[@]}" ps || podman ps --filter "name=lab-"
;;
build)
build_images
;;
down)
"${COMPOSE[@]}" down
;;
down-v)
"${COMPOSE[@]}" down -v
;;
status)
"${COMPOSE[@]}" ps || podman ps --filter "name=lab-"
;;
logs)
"${COMPOSE[@]}" logs -f --tail=100
;;
*)
echo "用法:$0 [up|build|down|down-v|status|logs]" >&2
exit 1
;;
esac