#!/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