fix(dev): isolate dev environment ports and fix env loading
- docker-compose.yaml: production mode uses expose (container-only) for Redis/PostgreSQL instead of ports (host-mapped) - docker-compose.dev.yml: dev override maps Redis 6381 and PostgreSQL 5435 to avoid conflicts with other projects (pms-redis 6379, geo_redis 6380, geo_db 5433) - config.py: fix empty env var handling — only skip .env override when os.environ[key] is non-empty; load .env, .env.dev, .env.local in sequence - scripts/dev-start.sh: manage agentkit-specific Docker containers - .gitignore: add .env.dev and .env.local (contain API keys)
This commit is contained in:
parent
754d70623c
commit
484b7ddb95
|
|
@ -44,6 +44,8 @@ src/agentkit/server/static/
|
||||||
|
|
||||||
# Env
|
# Env
|
||||||
.env
|
.env
|
||||||
|
.env.dev
|
||||||
|
.env.local
|
||||||
|
|
||||||
# Runtime data (auth DB, conversation DB, etc.)
|
# Runtime data (auth DB, conversation DB, etc.)
|
||||||
data/
|
data/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# 开发环境 override
|
||||||
|
# =============================================================================
|
||||||
|
# 用法:docker compose -f docker-compose.yaml -f docker-compose.dev.yml up -d redis postgres
|
||||||
|
#
|
||||||
|
# 仅启动 redis + postgres(agentkit 在宿主机运行),映射端口到 6381/5435
|
||||||
|
# 避免与 pms-redis(6379) / geo_redis(6380) / geo_db(5433) 端口冲突
|
||||||
|
#
|
||||||
|
# .env.dev 应包含:
|
||||||
|
# REDIS_URL=redis://127.0.0.1:6381/0
|
||||||
|
# DATABASE_URL=postgresql+asyncpg://agentkit:agentkit@127.0.0.1:5435/agentkit
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
services:
|
||||||
|
# 开发模式不启动 agentkit 容器(在宿主机运行)
|
||||||
|
agentkit:
|
||||||
|
profiles: ["never"]
|
||||||
|
|
||||||
|
redis:
|
||||||
|
ports:
|
||||||
|
- "6381:6379"
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
ports:
|
||||||
|
- "5435:5432"
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
version: "3.8"
|
version: "3.8"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# 生产部署配置
|
||||||
|
# =============================================================================
|
||||||
|
# 启动:docker compose up -d
|
||||||
|
# agentkit 容器内通过 service name (redis/postgres) 连接,不暴露中间件端口
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
services:
|
services:
|
||||||
agentkit:
|
agentkit:
|
||||||
build: .
|
build: .
|
||||||
|
|
@ -8,8 +15,12 @@ services:
|
||||||
- "8001:8001"
|
- "8001:8001"
|
||||||
env_file: .env
|
env_file: .env
|
||||||
environment:
|
environment:
|
||||||
|
# 容器间通信:使用 service name,不依赖宿主机端口
|
||||||
- REDIS_URL=redis://redis:6379/0
|
- REDIS_URL=redis://redis:6379/0
|
||||||
- DATABASE_URL=postgresql+asyncpg://agentkit:agentkit@postgres:5432/agentkit
|
- DATABASE_URL=postgresql+asyncpg://agentkit:agentkit@postgres:5432/agentkit
|
||||||
|
- AGENTKIT_BUS_BACKEND=redis
|
||||||
|
- AGENTKIT_SESSION_BACKEND=redis
|
||||||
|
- AGENTKIT_TASK_STORE_BACKEND=redis
|
||||||
depends_on:
|
depends_on:
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
|
@ -25,8 +36,9 @@ services:
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
ports:
|
# 生产模式不暴露端口到宿主机,仅容器间可达
|
||||||
- "6379:6379"
|
expose:
|
||||||
|
- "6379"
|
||||||
volumes:
|
volumes:
|
||||||
- redisdata:/data
|
- redisdata:/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
|
|
@ -38,8 +50,9 @@ services:
|
||||||
|
|
||||||
postgres:
|
postgres:
|
||||||
image: pgvector/pgvector:pg15
|
image: pgvector/pgvector:pg15
|
||||||
ports:
|
# 生产模式不暴露端口到宿主机,仅容器间可达
|
||||||
- "5432:5432"
|
expose:
|
||||||
|
- "5432"
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: agentkit
|
POSTGRES_USER: agentkit
|
||||||
POSTGRES_PASSWORD: agentkit
|
POSTGRES_PASSWORD: agentkit
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,14 @@
|
||||||
# Python >= 3.11, Node.js >= 18, Redis, PostgreSQL (均自动检查)
|
# Python >= 3.11, Node.js >= 18, Redis, PostgreSQL (均自动检查)
|
||||||
# --tauri 需要:Rust 工具链(rustup / brew install rust)
|
# --tauri 需要:Rust 工具链(rustup / brew install rust)
|
||||||
#
|
#
|
||||||
|
# 端口(与 .env.dev 保持一致):
|
||||||
|
# 18001 — AgentKit 后端 API
|
||||||
|
# 18002 — Web GUI(前端 + 内置静态服务)
|
||||||
|
# 15173 — Vite 开发服务器(--tauri 模式)
|
||||||
|
# 15174 — Vite HMR websocket
|
||||||
|
# 6381 — Redis(agentkit 专属容器,避免与 pms-redis:6379 / geo_redis:6380 冲突)
|
||||||
|
# 5435 — PostgreSQL+pgvector(agentkit 专属容器,避免与 geo_db:5433 冲突)
|
||||||
|
#
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
@ -49,12 +57,14 @@ Fischer AgentKit — 本地开发环境启动
|
||||||
|
|
||||||
模式说明:
|
模式说明:
|
||||||
默认 Web 模式:agentkit gui (前后端 + 内置静态服务)
|
默认 Web 模式:agentkit gui (前后端 + 内置静态服务)
|
||||||
--tauri Tauri 模式:后端 API + Vite (:5173) + Tauri 桌面窗口
|
--tauri Tauri 模式:后端 API + Vite (:15173) + Tauri 桌面窗口
|
||||||
|
|
||||||
端口映射:
|
端口映射:
|
||||||
8000 — 后端 API
|
18001 — 后端 API
|
||||||
8002 — Web GUI / 前端静态服务
|
18002 — Web GUI / 前端静态服务
|
||||||
5173 — Vite 开发服务器(--tauri 模式)
|
15173 — Vite 开发服务器(--tauri 模式)
|
||||||
|
6381 — Redis(agentkit 专属容器)
|
||||||
|
5435 — PostgreSQL+pgvector(agentkit 专属容器)
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,11 +122,11 @@ print_status() {
|
||||||
echo -e "${CYAN}═══════════════════════════════════════════════════${NC}"
|
echo -e "${CYAN}═══════════════════════════════════════════════════${NC}"
|
||||||
echo -e "$([[ $S_DEPS -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_DEPS -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") 依赖检查"
|
echo -e "$([[ $S_DEPS -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_DEPS -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") 依赖检查"
|
||||||
echo -e "$([[ $S_ENV -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_ENV -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") 环境配置"
|
echo -e "$([[ $S_ENV -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_ENV -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") 环境配置"
|
||||||
echo -e "$([[ $S_REDIS -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_REDIS -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") Redis"
|
echo -e "$([[ $S_REDIS -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_REDIS -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") Redis (:6381)"
|
||||||
echo -e "$([[ $S_PG -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_PG -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") PostgreSQL"
|
echo -e "$([[ $S_PG -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_PG -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") PostgreSQL (:5435)"
|
||||||
echo -e "$([[ $S_BACKEND -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_BACKEND -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") 后端服务 (:8000)"
|
echo -e "$([[ $S_BACKEND -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_BACKEND -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") 后端服务 (:18001)"
|
||||||
if [[ $MODE == "gui" || $MODE == "tauri" ]]; then
|
if [[ $MODE == "gui" || $MODE == "tauri" ]]; then
|
||||||
echo -e "$([[ $S_FRONTEND -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_FRONTEND -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") 前端服务 (:8002)"
|
echo -e "$([[ $S_FRONTEND -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_FRONTEND -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") 前端服务 (:18002)"
|
||||||
fi
|
fi
|
||||||
if [[ $MODE == "tauri" ]]; then
|
if [[ $MODE == "tauri" ]]; then
|
||||||
echo -e "$([[ $S_TAURI -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_TAURI -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") Tauri 客户端"
|
echo -e "$([[ $S_TAURI -eq 2 ]] && echo " ${GREEN}✓${NC}" || [[ $S_TAURI -eq 3 ]] && echo " ${RED}✗${NC}" || echo " ${YELLOW}○${NC}") Tauri 客户端"
|
||||||
|
|
@ -180,30 +190,23 @@ check_redis() {
|
||||||
section "检查 Redis"
|
section "检查 Redis"
|
||||||
set_status redis 1
|
set_status redis 1
|
||||||
|
|
||||||
if command -v redis-cli &>/dev/null && redis-cli ping 2>/dev/null | grep -q PONG; then
|
# agentkit 专属容器映射到 6381,避免与 pms-redis(6379) / geo_redis(6380) 冲突
|
||||||
ok "Redis 运行中"
|
if redis-cli -h 127.0.0.1 -p 6381 ping 2>/dev/null | grep -q PONG; then
|
||||||
|
ok "Redis 运行中 (127.0.0.1:6381, agentkit 专属容器)"
|
||||||
set_status redis 2
|
set_status redis 2
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Docker 方式
|
warn "Redis 未运行 (6381),启动 agentkit 专属 Docker 容器..."
|
||||||
local name="fischer-redis-dev"
|
if docker compose -f docker-compose.yaml -f docker-compose.dev.yml up -d redis &>/dev/null; then
|
||||||
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^${name}$"; then
|
|
||||||
ok "Redis 容器运行中"
|
|
||||||
set_status redis 2
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
warn "Redis 未运行,尝试启动 Docker 容器..."
|
|
||||||
if docker run -d --name "$name" -p 6379:6379 redis:7-alpine &>/dev/null; then
|
|
||||||
sleep 2
|
sleep 2
|
||||||
if docker exec "$name" redis-cli ping 2>/dev/null | grep -q PONG; then
|
if redis-cli -h 127.0.0.1 -p 6381 ping 2>/dev/null | grep -q PONG; then
|
||||||
ok "Redis Docker 容器启动成功 (:6379)"
|
ok "Redis Docker 容器启动成功 (127.0.0.1:6381)"
|
||||||
set_status redis 2
|
set_status redis 2
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fail "Redis 启动失败(请确保 Docker 运行中,或手动启动 Redis)"
|
fail "Redis 启动失败(请确保 Docker 运行中)"
|
||||||
set_status redis 3
|
set_status redis 3
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
@ -212,30 +215,18 @@ check_postgres() {
|
||||||
section "检查 PostgreSQL"
|
section "检查 PostgreSQL"
|
||||||
set_status pg 1
|
set_status pg 1
|
||||||
|
|
||||||
if lsof -i :5432 2>/dev/null | grep -q LISTEN; then
|
# agentkit 专属容器映射到 5435,避免与 geo_db(5433) 冲突
|
||||||
ok "PostgreSQL 已在 :5432 监听"
|
if PGPASSWORD=agentkit psql -h 127.0.0.1 -p 5435 -U agentkit -d agentkit -c "SELECT 1" &>/dev/null; then
|
||||||
|
ok "PostgreSQL 运行中 (127.0.0.1:5435, agentkit 专属容器)"
|
||||||
set_status pg 2
|
set_status pg 2
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Docker 方式
|
warn "PostgreSQL 未运行 (5435),启动 agentkit 专属 Docker 容器..."
|
||||||
local name="fischer-pg-dev"
|
if docker compose -f docker-compose.yaml -f docker-compose.dev.yml up -d postgres &>/dev/null; then
|
||||||
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^${name}$"; then
|
|
||||||
ok "PostgreSQL Docker 容器运行中"
|
|
||||||
set_status pg 2
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
warn "PostgreSQL 未在 :5432 运行,尝试启动 Docker 容器..."
|
|
||||||
if docker run -d --name "$name" \
|
|
||||||
-p 5432:5432 \
|
|
||||||
-e POSTGRES_USER=agentkit \
|
|
||||||
-e POSTGRES_PASSWORD=agentkit \
|
|
||||||
-e POSTGRES_DB=agentkit \
|
|
||||||
pgvector/pgvector:pg15 &>/dev/null; then
|
|
||||||
sleep 3
|
sleep 3
|
||||||
if docker exec "$name" pg_isready -U agentkit &>/dev/null; then
|
if PGPASSWORD=agentkit psql -h 127.0.0.1 -p 5435 -U agentkit -d agentkit -c "SELECT 1" &>/dev/null; then
|
||||||
ok "PostgreSQL Docker 容器启动成功 (:5432)"
|
ok "PostgreSQL Docker 容器启动成功 (127.0.0.1:5435)"
|
||||||
set_status pg 2
|
set_status pg 2
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
@ -281,17 +272,17 @@ start_backend() {
|
||||||
section "启动后端服务"
|
section "启动后端服务"
|
||||||
set_status backend 1
|
set_status backend 1
|
||||||
|
|
||||||
info "启动后端 API (:8000)..."
|
info "启动后端 API (:18001)..."
|
||||||
source .venv/bin/activate
|
source .venv/bin/activate
|
||||||
agentkit serve --port 8000 &
|
agentkit serve --port 18001 &
|
||||||
BACKEND_PID=$!
|
BACKEND_PID=$!
|
||||||
|
|
||||||
# 等待健康检查就绪(最多 60 秒)
|
# 等待健康检查就绪(最多 60 秒)
|
||||||
info "等待后端就绪..."
|
info "等待后端就绪..."
|
||||||
local attempt=0
|
local attempt=0
|
||||||
while [[ $attempt -lt 60 ]]; do
|
while [[ $attempt -lt 60 ]]; do
|
||||||
if curl -sf http://127.0.0.1:8000/api/v1/health &>/dev/null; then
|
if curl -sf http://127.0.0.1:18001/api/v1/health &>/dev/null; then
|
||||||
ok "后端 API 就绪 (http://127.0.0.1:8000, PID $BACKEND_PID)"
|
ok "后端 API 就绪 (http://127.0.0.1:18001, PID $BACKEND_PID)"
|
||||||
set_status backend 2
|
set_status backend 2
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
@ -318,17 +309,17 @@ start_gui() {
|
||||||
section "启动 Web GUI"
|
section "启动 Web GUI"
|
||||||
set_status frontend 1
|
set_status frontend 1
|
||||||
|
|
||||||
info "启动 Web GUI (:8002)..."
|
info "启动 Web GUI (:18002)..."
|
||||||
source .venv/bin/activate
|
source .venv/bin/activate
|
||||||
agentkit gui --port 8002 &
|
agentkit gui --port 18002 &
|
||||||
GUI_PID=$!
|
GUI_PID=$!
|
||||||
|
|
||||||
# 等待就绪
|
# 等待就绪
|
||||||
info "等待 Web GUI 就绪..."
|
info "等待 Web GUI 就绪..."
|
||||||
local attempt=0
|
local attempt=0
|
||||||
while [[ $attempt -lt 60 ]]; do
|
while [[ $attempt -lt 60 ]]; do
|
||||||
if curl -sf http://127.0.0.1:8002/api/v1/health &>/dev/null; then
|
if curl -sf http://127.0.0.1:18002/api/v1/health &>/dev/null; then
|
||||||
ok "Web GUI 就绪 (http://127.0.0.1:8002, PID $GUI_PID)"
|
ok "Web GUI 就绪 (http://127.0.0.1:18002, PID $GUI_PID)"
|
||||||
set_status frontend 2
|
set_status frontend 2
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
@ -364,7 +355,7 @@ start_tauri() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
info "启动 Tauri 桌面客户端..."
|
info "启动 Tauri 桌面客户端..."
|
||||||
info " (Vite → :5173, 后端 API → :8000)"
|
info " (Vite → :15173, 后端 API → :18001)"
|
||||||
cd "$FE_DIR"
|
cd "$FE_DIR"
|
||||||
npm run tauri dev &
|
npm run tauri dev &
|
||||||
TAURI_PID=$!
|
TAURI_PID=$!
|
||||||
|
|
@ -400,7 +391,7 @@ stop_services() {
|
||||||
echo ""
|
echo ""
|
||||||
info "正在停止所有服务..."
|
info "正在停止所有服务..."
|
||||||
|
|
||||||
for port in 8000 8001 8002 5173; do
|
for port in 18001 18002 15173 15174; do
|
||||||
local pid=$(lsof -ti :$port 2>/dev/null || true)
|
local pid=$(lsof -ti :$port 2>/dev/null || true)
|
||||||
if [[ -n "$pid" ]]; then
|
if [[ -n "$pid" ]]; then
|
||||||
kill $pid 2>/dev/null && ok "端口 $port 已停止" || true
|
kill $pid 2>/dev/null && ok "端口 $port 已停止" || true
|
||||||
|
|
@ -474,14 +465,14 @@ if [[ $FAILED -eq 0 ]]; then
|
||||||
echo -e "${CYAN}═══════════════════════════════════════════════════${NC}"
|
echo -e "${CYAN}═══════════════════════════════════════════════════${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
if [[ $MODE == "gui" ]]; then
|
if [[ $MODE == "gui" ]]; then
|
||||||
echo -e " Web GUI: ${GREEN}http://localhost:8002${NC}"
|
echo -e " Web GUI: ${GREEN}http://localhost:18002${NC}"
|
||||||
echo " (在浏览器中打开,或直接在 http://localhost:8002 访问)"
|
echo " (在浏览器中打开,或直接在 http://localhost:18002 访问)"
|
||||||
elif [[ $MODE == "tauri" ]]; then
|
elif [[ $MODE == "tauri" ]]; then
|
||||||
echo -e " 后端 API: ${GREEN}http://localhost:8000${NC}"
|
echo -e " 后端 API: ${GREEN}http://localhost:18001${NC}"
|
||||||
echo -e " Vite 热重载: ${GREEN}http://localhost:5173${NC}"
|
echo -e " Vite 热重载: ${GREEN}http://localhost:15173${NC}"
|
||||||
echo " Tauri 桌面窗口应已自动打开"
|
echo " Tauri 桌面窗口应已自动打开"
|
||||||
elif [[ $MODE == "serve" ]]; then
|
elif [[ $MODE == "serve" ]]; then
|
||||||
echo -e " 后端 API: ${GREEN}http://localhost:8000${NC}"
|
echo -e " 后端 API: ${GREEN}http://localhost:18001${NC}"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
echo -e " ${YELLOW}按 Ctrl+C 停止所有服务${NC}"
|
echo -e " ${YELLOW}按 Ctrl+C 停止所有服务${NC}"
|
||||||
|
|
@ -491,7 +482,7 @@ else
|
||||||
echo -e "${CYAN}═══════════════════════════════════════════════════${NC}"
|
echo -e "${CYAN}═══════════════════════════════════════════════════${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
echo -e " 诊断命令:"
|
echo -e " 诊断命令:"
|
||||||
echo -e " 查看日志: ${CYAN}curl http://127.0.0.1:8000/api/v1/health${NC}"
|
echo -e " 查看日志: ${CYAN}curl http://127.0.0.1:18001/api/v1/health${NC}"
|
||||||
echo -e " 停止服务: ${CYAN}bash scripts/dev-stop.sh${NC}"
|
echo -e " 停止服务: ${CYAN}bash scripts/dev-stop.sh${NC}"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
|
||||||
|
|
@ -555,7 +555,11 @@ def load_dotenv(
|
||||||
key, _, value = line.partition("=")
|
key, _, value = line.partition("=")
|
||||||
key = key.strip()
|
key = key.strip()
|
||||||
value = value.strip().strip("\"'")
|
value = value.strip().strip("\"'")
|
||||||
if not key or key in os.environ:
|
# Skip only if key is set to a non-empty value in the environment.
|
||||||
|
# An empty/whitespace-only value (e.g. from a shell template like
|
||||||
|
# `${VAR:-}` that expanded to nothing) is treated as "not set" so
|
||||||
|
# subsequent .env files can still provide a real value.
|
||||||
|
if not key or (key in os.environ and os.environ[key].strip()):
|
||||||
continue
|
continue
|
||||||
# Apply allowlist if provided
|
# Apply allowlist if provided
|
||||||
if prefixes is not None or exact is not None:
|
if prefixes is not None or exact is not None:
|
||||||
|
|
@ -579,8 +583,10 @@ def load_config_with_dotenv(config_path: str | Path) -> ServerConfig:
|
||||||
This is the canonical way to load config in all CLI commands and app factory.
|
This is the canonical way to load config in all CLI commands and app factory.
|
||||||
"""
|
"""
|
||||||
config_path = str(config_path)
|
config_path = str(config_path)
|
||||||
dotenv = Path(config_path).parent / ".env"
|
config_dir = Path(config_path).parent
|
||||||
load_dotenv(dotenv)
|
# Load .env, .env.dev, .env.local in order (first non-empty value wins).
|
||||||
|
for candidate in (".env", ".env.dev", ".env.local"):
|
||||||
|
load_dotenv(config_dir / candidate)
|
||||||
return ServerConfig.from_yaml(config_path)
|
return ServerConfig.from_yaml(config_path)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue