134 lines
3.9 KiB
Bash
Executable File
134 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
cd "$PROJECT_DIR"
|
||
|
||
ACTION="${1:-status}"
|
||
ENV_FILE="${PROJECT_DIR}/.env"
|
||
COMPOSE_FILE="${COMPOSE_FILE_PATH:-docker-compose.yml}"
|
||
|
||
require_cmd() {
|
||
command -v "$1" >/dev/null 2>&1 || {
|
||
echo "[错误] 缺少命令: $1"
|
||
exit 1
|
||
}
|
||
}
|
||
|
||
require_cmd docker
|
||
require_cmd curl
|
||
|
||
if ! docker info >/dev/null 2>&1; then
|
||
echo "[错误] Docker 服务未启动。"
|
||
exit 1
|
||
fi
|
||
|
||
if [[ ! -f "$ENV_FILE" && -f "${PROJECT_DIR}/.env.example" ]]; then
|
||
cp "${PROJECT_DIR}/.env.example" "$ENV_FILE"
|
||
echo "[信息] 已根据 .env.example 生成 .env"
|
||
fi
|
||
|
||
compose() {
|
||
docker compose -f "$COMPOSE_FILE" "$@"
|
||
}
|
||
|
||
compose_quiet() {
|
||
local tmp_log
|
||
tmp_log="$(mktemp)"
|
||
if compose "$@" >"$tmp_log" 2>&1; then
|
||
rm -f "$tmp_log"
|
||
return 0
|
||
fi
|
||
cat "$tmp_log"
|
||
rm -f "$tmp_log"
|
||
return 1
|
||
}
|
||
|
||
backend_health() {
|
||
curl -fsS "http://127.0.0.1:${BACKEND_PORT:-8000}/healthz" >/dev/null
|
||
}
|
||
|
||
redis_health() {
|
||
local redis_password
|
||
redis_password="$(grep -E '^REDIS_PASSWORD=' "$ENV_FILE" | cut -d'=' -f2- || true)"
|
||
compose exec -T redis redis-cli -a "${redis_password:-pmflow_redis_pass}" ping | grep -q PONG
|
||
}
|
||
|
||
db_health() {
|
||
local db_user db_name
|
||
db_user="$(grep -E '^POSTGRES_USER=' "$ENV_FILE" | cut -d'=' -f2- || true)"
|
||
db_name="$(grep -E '^POSTGRES_DB=' "$ENV_FILE" | cut -d'=' -f2- || true)"
|
||
compose exec -T db pg_isready -U "${db_user:-pmflow}" -d "${db_name:-pmflow}" >/dev/null
|
||
}
|
||
|
||
case "$ACTION" in
|
||
start)
|
||
echo "[信息] 编排文件: ${COMPOSE_FILE}"
|
||
compose_quiet up -d
|
||
echo "[完成] 服务栈已启动"
|
||
;;
|
||
restart)
|
||
echo "[信息] 编排文件: ${COMPOSE_FILE}"
|
||
compose_quiet down
|
||
compose_quiet up -d
|
||
echo "[完成] 服务栈已重启"
|
||
;;
|
||
stop)
|
||
echo "[信息] 编排文件: ${COMPOSE_FILE}"
|
||
compose_quiet down
|
||
echo "[完成] 服务栈已停止"
|
||
;;
|
||
status|ps)
|
||
echo "[信息] 编排文件: ${COMPOSE_FILE}"
|
||
compose ps
|
||
;;
|
||
logs)
|
||
echo "[信息] 编排文件: ${COMPOSE_FILE}"
|
||
compose logs --tail=200 "${2:-}"
|
||
;;
|
||
health)
|
||
backend_health && echo "[完成] 后端健康检查通过(/healthz)"
|
||
db_health && echo "[完成] 数据库健康检查通过(pg_isready)"
|
||
redis_health && echo "[完成] Redis 健康检查通过(PING)"
|
||
;;
|
||
dev-start)
|
||
COMPOSE_FILE="docker-compose.dev.yml"
|
||
echo "[信息] 编排文件: ${COMPOSE_FILE}"
|
||
compose_quiet up -d
|
||
echo "[完成] 开发环境服务栈已启动"
|
||
;;
|
||
dev-restart)
|
||
COMPOSE_FILE="docker-compose.dev.yml"
|
||
echo "[信息] 编排文件: ${COMPOSE_FILE}"
|
||
compose_quiet down
|
||
compose_quiet up -d
|
||
echo "[完成] 开发环境服务栈已重启"
|
||
;;
|
||
dev-stop)
|
||
COMPOSE_FILE="docker-compose.dev.yml"
|
||
echo "[信息] 编排文件: ${COMPOSE_FILE}"
|
||
compose_quiet down
|
||
echo "[完成] 开发环境服务栈已停止"
|
||
;;
|
||
dev-status|dev-ps)
|
||
COMPOSE_FILE="docker-compose.dev.yml"
|
||
echo "[信息] 编排文件: ${COMPOSE_FILE}"
|
||
compose ps
|
||
;;
|
||
dev-logs)
|
||
COMPOSE_FILE="docker-compose.dev.yml"
|
||
echo "[信息] 编排文件: ${COMPOSE_FILE}"
|
||
compose logs --tail=200 "${2:-}"
|
||
;;
|
||
dev-health)
|
||
COMPOSE_FILE="docker-compose.dev.yml"
|
||
backend_health && echo "[完成] 后端健康检查通过(/healthz)"
|
||
db_health && echo "[完成] 数据库健康检查通过(pg_isready)"
|
||
redis_health && echo "[完成] Redis 健康检查通过(PING)"
|
||
;;
|
||
*)
|
||
echo "用法: $0 {start|restart|stop|status|ps|logs [service]|health|dev-start|dev-restart|dev-stop|dev-status|dev-ps|dev-logs [service]|dev-health}"
|
||
exit 1
|
||
;;
|
||
esac
|