- 添加 database_url_targets_local_port 函数验证数据库URL端口匹配 - 新增 database_url_matches_container 变量标识数据库URL与容器匹配状态 - 更新 postgres_port 变量获取容器实际端口值 - 重构数据库URL配置条件判断逻辑 - 添加容器凭证刷新提示信息 - 优化Docker数据库创建条件判断流程
192 lines
6.1 KiB
Bash
Executable File
192 lines
6.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
|
load_local_env() {
|
|
local env_file
|
|
for env_file in "${PROJECT_ROOT}/.env" "${PROJECT_ROOT}/.env.local"; do
|
|
[[ -f "$env_file" ]] || continue
|
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
|
[[ -z "$line" || "$line" == \#* || "$line" != *=* ]] && continue
|
|
local key="${line%%=*}"
|
|
local value="${line#*=}"
|
|
[[ "$key" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] || continue
|
|
if [[ "$value" == \"*\" && "$value" == *\" ]]; then
|
|
value="${value:1:${#value}-2}"
|
|
elif [[ "$value" == \'*\' && "$value" == *\' ]]; then
|
|
value="${value:1:${#value}-2}"
|
|
fi
|
|
export "$key=$value"
|
|
done < "$env_file"
|
|
done
|
|
}
|
|
|
|
load_local_env
|
|
|
|
find_postgres_container() {
|
|
local candidate compose_container
|
|
|
|
if [[ -n "${AI_GATEWAY_PG_CONTAINER:-}" ]]; then
|
|
if docker inspect "$AI_GATEWAY_PG_CONTAINER" >/dev/null 2>&1; then
|
|
printf '%s\n' "$AI_GATEWAY_PG_CONTAINER"
|
|
return 0
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
for candidate in easyai-pgvector postgres; do
|
|
if docker inspect "$candidate" >/dev/null 2>&1; then
|
|
printf '%s\n' "$candidate"
|
|
return 0
|
|
fi
|
|
done
|
|
|
|
compose_container="$(
|
|
docker compose -f "${PROJECT_ROOT}/docker-compose.yml" ps -q postgres 2>/dev/null \
|
|
| head -n 1
|
|
)"
|
|
if [[ -n "$compose_container" ]] && docker inspect "$compose_container" >/dev/null 2>&1; then
|
|
printf '%s\n' "$compose_container"
|
|
return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
postgres_host_port() {
|
|
local mapping port
|
|
mapping="$(docker port "$1" 5432/tcp 2>/dev/null | head -n 1)"
|
|
port="${mapping##*:}"
|
|
if [[ "$port" =~ ^[0-9]+$ ]]; then
|
|
printf '%s\n' "$port"
|
|
else
|
|
printf '5432\n'
|
|
fi
|
|
}
|
|
|
|
database_url_targets_local_port() {
|
|
local database_url="$1"
|
|
local expected_port="$2"
|
|
local authority host_port port
|
|
|
|
case "$database_url" in
|
|
postgres://*|postgresql://*) ;;
|
|
*) return 1 ;;
|
|
esac
|
|
|
|
authority="${database_url#*://}"
|
|
authority="${authority%%/*}"
|
|
host_port="${authority##*@}"
|
|
|
|
case "$host_port" in
|
|
localhost|127.0.0.1|\[::1\])
|
|
port=5432
|
|
;;
|
|
localhost:*|127.0.0.1:*|\[::1\]:*)
|
|
port="${host_port##*:}"
|
|
;;
|
|
*)
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
[[ "$port" == "$expected_port" ]]
|
|
}
|
|
|
|
stop_stale_api_processes() {
|
|
local api_port="${HTTP_ADDR:-:8088}"
|
|
api_port="${api_port##*:}"
|
|
local api_cwd="${PROJECT_ROOT}/apps/api"
|
|
|
|
if command -v pgrep >/dev/null 2>&1; then
|
|
while read -r pid; do
|
|
[[ -z "$pid" || "$pid" == "$$" ]] && continue
|
|
local cwd
|
|
cwd="$(lsof -a -p "$pid" -d cwd -Fn 2>/dev/null | awk '/^n/ {print substr($0, 2); exit}')"
|
|
if [[ "$cwd" == "$api_cwd" ]]; then
|
|
echo "[ai-gateway] stopping stale go-watch process: ${pid}"
|
|
kill "$pid" 2>/dev/null || true
|
|
fi
|
|
done < <(pgrep -f "go-watch\\.mjs -- go run ./cmd/gateway" || true)
|
|
fi
|
|
|
|
if ! command -v lsof >/dev/null 2>&1; then
|
|
return
|
|
fi
|
|
|
|
local pids
|
|
pids="$(lsof -tiTCP:"$api_port" -sTCP:LISTEN 2>/dev/null || true)"
|
|
[[ -z "$pids" ]] && return
|
|
|
|
while read -r pid; do
|
|
[[ -z "$pid" ]] && continue
|
|
local cwd command
|
|
cwd="$(lsof -a -p "$pid" -d cwd -Fn 2>/dev/null | awk '/^n/ {print substr($0, 2); exit}')"
|
|
command="$(ps -p "$pid" -o command= 2>/dev/null || true)"
|
|
if [[ "$cwd" == "$api_cwd" || "$command" == *"easyai-ai-gateway"* ]]; then
|
|
echo "[ai-gateway] freeing API port ${api_port}, stopping stale process: ${pid}"
|
|
kill "$pid" 2>/dev/null || true
|
|
else
|
|
echo "[ai-gateway] port ${api_port} is used by an unrelated process: ${pid} ${command}" >&2
|
|
exit 1
|
|
fi
|
|
done <<< "$pids"
|
|
|
|
sleep 0.5
|
|
}
|
|
|
|
database_url_was_configured=0
|
|
pg_container_was_configured=0
|
|
database_url_matches_container=0
|
|
[[ -n "${AI_GATEWAY_DATABASE_URL:-}" ]] && database_url_was_configured=1
|
|
[[ -n "${AI_GATEWAY_PG_CONTAINER:-}" ]] && pg_container_was_configured=1
|
|
|
|
postgres_container="$(find_postgres_container || true)"
|
|
postgres_port=5432
|
|
if [[ -n "$postgres_container" ]]; then
|
|
export AI_GATEWAY_PG_CONTAINER="$postgres_container"
|
|
postgres_port="$(postgres_host_port "$postgres_container")"
|
|
if [[ "$database_url_was_configured" == "1" ]] \
|
|
&& database_url_targets_local_port "$AI_GATEWAY_DATABASE_URL" "$postgres_port"; then
|
|
database_url_matches_container=1
|
|
fi
|
|
elif [[ "$pg_container_was_configured" == "1" ]]; then
|
|
echo "[ai-gateway] configured PostgreSQL container is unavailable; using the database URL without Docker database creation" >&2
|
|
fi
|
|
|
|
export AI_GATEWAY_PG_USER="${AI_GATEWAY_PG_USER:-easyai}"
|
|
if [[ -z "${AI_GATEWAY_PG_PASSWORD:-}" && -n "$postgres_container" ]]; then
|
|
AI_GATEWAY_PG_PASSWORD="$(
|
|
docker inspect "$postgres_container" --format '{{range .Config.Env}}{{println .}}{{end}}' \
|
|
| awk -F= '$1 == "POSTGRES_PASSWORD" {print $2; exit}'
|
|
)"
|
|
export AI_GATEWAY_PG_PASSWORD
|
|
fi
|
|
export AI_GATEWAY_PG_PASSWORD="${AI_GATEWAY_PG_PASSWORD:-easyai2025}"
|
|
export AI_GATEWAY_DATABASE_NAME="${AI_GATEWAY_DATABASE_NAME:-easyai_ai_gateway}"
|
|
if [[ "$database_url_was_configured" == "0" || "$database_url_matches_container" == "1" ]]; then
|
|
export AI_GATEWAY_DATABASE_URL="postgresql://${AI_GATEWAY_PG_USER}:${AI_GATEWAY_PG_PASSWORD}@localhost:${postgres_port}/${AI_GATEWAY_DATABASE_NAME}?sslmode=disable"
|
|
fi
|
|
|
|
echo "[ai-gateway] using configured local database connection (credentials redacted)"
|
|
if [[ "$database_url_matches_container" == "1" ]]; then
|
|
echo "[ai-gateway] refreshed credentials from local PostgreSQL container: ${postgres_container}"
|
|
fi
|
|
|
|
if [[ "${AI_GATEWAY_SKIP_DB_CREATE:-}" == "1" ]]; then
|
|
echo "[ai-gateway] skipping Docker database creation"
|
|
elif [[ -n "$postgres_container" \
|
|
&& ( "$database_url_was_configured" == "0" \
|
|
|| "$pg_container_was_configured" == "1" \
|
|
|| "$database_url_matches_container" == "1" ) ]]; then
|
|
scripts/create-database.sh
|
|
elif [[ -n "$postgres_container" ]]; then
|
|
echo "[ai-gateway] preserving configured database URL; skipping Docker database creation"
|
|
else
|
|
echo "[ai-gateway] no matching Docker database container selected; skipping database creation"
|
|
fi
|
|
pnpm nx run api:migrate
|
|
stop_stale_api_processes
|
|
exec pnpm nx run-many -t dev -p api web --parallel=2
|