fix: resolve WebUI API proxy ECONNREFUSED and configmap placeholder issues
Some checks failed
Build and Deploy GooSeek / build-and-deploy (push) Has been cancelled

- Fix route handlers to use API_GATEWAY_URL env var with correct K8s fallback
  instead of localhost:3015
- Replace ${} placeholders in configmap.yaml with actual static values to
  prevent kustomize from overwriting envsubst-generated config
- Separate secrets into dedicated secrets.yaml for envsubst processing
- Update deploy.sh to only envsubst secrets (configmap now has static values)

Made-with: Cursor
This commit is contained in:
home
2026-03-03 04:16:57 +03:00
parent 32102c379a
commit 1c1a10eb35
6 changed files with 92 additions and 94 deletions

View File

@@ -29,41 +29,24 @@ data:
OLLAMA_MODEL: "qwen3.5:9b"
OLLAMA_EMBEDDING_MODEL: "qwen3-embedding:0.6b"
OLLAMA_NUM_PARALLEL: "2"
DEFAULT_LLM_MODEL: "${DEFAULT_LLM_MODEL}"
DEFAULT_LLM_PROVIDER: "${DEFAULT_LLM_PROVIDER}"
TIMEWEB_API_BASE_URL: "${TIMEWEB_API_BASE_URL}"
TIMEWEB_AGENT_ACCESS_ID: "${TIMEWEB_AGENT_ACCESS_ID}"
TRAVELPAYOUTS_TOKEN: "${TRAVELPAYOUTS_TOKEN}"
NEXT_PUBLIC_ENABLED_ROUTES: "${NEXT_PUBLIC_ENABLED_ROUTES}"
NEXT_PUBLIC_TWOGIS_API_KEY: "${NEXT_PUBLIC_TWOGIS_API_KEY}"
S3_ENDPOINT: "${S3_ENDPOINT}"
S3_ACCESS_KEY: "${S3_ACCESS_KEY}"
S3_SECRET_KEY: "${S3_SECRET_KEY}"
S3_BUCKET: "${S3_BUCKET}"
S3_USE_SSL: "${S3_USE_SSL}"
S3_REGION: "${S3_REGION}"
S3_PUBLIC_URL: "${S3_PUBLIC_URL}"
SMTP_HOST: "${SMTP_HOST}"
SMTP_PORT: "${SMTP_PORT}"
SMTP_USER: "${SMTP_USER}"
SMTP_FROM: "${SMTP_FROM}"
SMTP_TLS: "${SMTP_TLS}"
DEFAULT_LLM_MODEL: "gpt-4o-mini"
DEFAULT_LLM_PROVIDER: "openai"
TIMEWEB_API_BASE_URL: "https://api.timeweb.cloud"
TIMEWEB_AGENT_ACCESS_ID: "9df5206a-86e8-4c8d-87a7-6b95eb0ecab0"
TRAVELPAYOUTS_TOKEN: "83465cb3013f97f6eed45d3567721244"
NEXT_PUBLIC_ENABLED_ROUTES: "/travel,/learning,/history,/medicine,/discover"
NEXT_PUBLIC_TWOGIS_API_KEY: "e5fd2c5b-a5bc-40ec-94b3-6b5a396ebba0"
S3_ENDPOINT: "minio:9000"
S3_ACCESS_KEY: "minioadmin"
S3_SECRET_KEY: "minioadmin"
S3_BUCKET: "gooseek-artifacts"
S3_USE_SSL: "false"
S3_REGION: "us-east-1"
S3_PUBLIC_URL: "https://storage.gooseek.ru"
SMTP_HOST: "smtp.timeweb.ru"
SMTP_PORT: "465"
SMTP_USER: "2fa@gooseek.ru"
SMTP_FROM: "GooSeek 2FA <2fa@gooseek.ru>"
SMTP_TLS: "true"
SITE_URL: "https://gooseek.ru"
SITE_NAME: "GooSeek"
---
apiVersion: v1
kind: Secret
metadata:
name: gooseek-secrets
namespace: gooseek
type: Opaque
stringData:
OPENAI_API_KEY: "${OPENAI_API_KEY}"
ANTHROPIC_API_KEY: "${ANTHROPIC_API_KEY}"
GEMINI_API_KEY: "${GEMINI_API_KEY}"
JWT_SECRET: "${JWT_SECRET}"
TIMEWEB_API_KEY: "${TIMEWEB_API_KEY}"
OLLAMA_API_TOKEN: "${OLLAMA_API_TOKEN}"
SMTP_PASSWORD: "${SMTP_PASSWORD}"
POSTGRES_USER: "gooseek"
POSTGRES_PASSWORD: "gooseek"

View File

@@ -71,12 +71,13 @@ echo "=== Pushing webui to registry ==="
docker push "$REGISTRY/gooseek/webui:$IMAGE_TAG"
docker push "$REGISTRY/gooseek/webui:latest"
# Generate configmap/secrets from .env via envsubst
# Generate secrets from .env via envsubst (configmap has static values)
echo ""
echo "=== Generating K8s manifests from .env ==="
echo "=== Generating K8s secrets from .env ==="
if command -v envsubst &> /dev/null && [ -f "$ENV_FILE" ]; then
envsubst < "$SCRIPT_DIR/configmap.yaml" > "$SCRIPT_DIR/_generated_configmap.yaml"
kubectl apply -f "$SCRIPT_DIR/_generated_configmap.yaml" -n gooseek
envsubst < "$SCRIPT_DIR/secrets.yaml" > "$SCRIPT_DIR/_generated_secrets.yaml"
kubectl apply -f "$SCRIPT_DIR/_generated_secrets.yaml" -n gooseek
rm -f "$SCRIPT_DIR/_generated_secrets.yaml"
# Generate monitoring manifests
envsubst < "$SCRIPT_DIR/monitoring.yaml" > "$SCRIPT_DIR/_generated_monitoring.yaml"

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Secret
metadata:
name: gooseek-secrets
namespace: gooseek
type: Opaque
stringData:
OPENAI_API_KEY: "${OPENAI_API_KEY}"
ANTHROPIC_API_KEY: "${ANTHROPIC_API_KEY}"
GEMINI_API_KEY: "${GEMINI_API_KEY}"
JWT_SECRET: "${JWT_SECRET}"
TIMEWEB_API_KEY: "${TIMEWEB_API_KEY}"
OLLAMA_API_TOKEN: "${OLLAMA_API_TOKEN}"
SMTP_PASSWORD: "${SMTP_PASSWORD}"
POSTGRES_USER: "gooseek"
POSTGRES_PASSWORD: "gooseek"

View File

@@ -1,34 +1,41 @@
import { NextRequest, NextResponse } from 'next/server';
const API_URL = process.env.API_URL || 'http://localhost:3015';
const API_GATEWAY =
process.env.API_GATEWAY_URL ||
process.env.API_URL ||
'http://api-gateway:3015';
export async function POST(request: NextRequest): Promise<NextResponse> {
const targetUrl = `${API_URL}/api/chat`;
const targetUrl = `${API_GATEWAY}/api/chat`;
const headers = new Headers();
const authHeader = request.headers.get('authorization');
if (authHeader) {
headers.set('Authorization', authHeader);
}
headers.set('Content-Type', 'application/json');
headers.set('Accept', 'application/x-ndjson');
try {
const body = await request.text();
const response = await fetch(targetUrl, {
method: 'POST',
headers,
body,
});
const contentType = response.headers.get('content-type') || 'application/x-ndjson';
const contentType =
response.headers.get('content-type') || 'application/x-ndjson';
const stream = response.body;
if (!stream) {
return NextResponse.json({ error: 'No response body' }, { status: 500 });
return NextResponse.json(
{ error: 'No response body' },
{ status: 500 },
);
}
return new NextResponse(stream, {
@@ -44,7 +51,7 @@ export async function POST(request: NextRequest): Promise<NextResponse> {
console.error('[Chat API Proxy] Error:', error);
return NextResponse.json(
{ error: 'Service unavailable' },
{ status: 503 }
{ status: 503 },
);
}
}

View File

@@ -1,6 +1,9 @@
import { NextRequest, NextResponse } from 'next/server';
const API_URL = process.env.API_URL || 'http://localhost:3015';
const API_URL =
process.env.API_GATEWAY_URL ||
process.env.API_URL ||
'http://api-gateway:3015';
async function proxyRequest(
request: NextRequest,