feat: gestiona rutas con proxy en Bun para /webhook y /metrics

Co-authored-by: aider (openrouter/openai/gpt-5) <aider@aider.chat>
webui
brobert 2 weeks ago
parent 296ab169f1
commit c97a805d43

@ -10,20 +10,35 @@ ENV DATA_DIR=/app/data
# Create data directory with proper permissions
RUN mkdir -p /app/data && chown -R bun:bun /app/data
# Install dependencies first (better layer caching)
# Install bot dependencies first (better layer caching)
COPY package.json bun.lock ./
RUN bun install
# Copy only necessary files
# Prepare and install web dependencies
COPY apps/web/package.json apps/web/
WORKDIR /app/apps/web
RUN bun install
# Copy sources
WORKDIR /app
COPY src/ ./src/
COPY index.ts ./
COPY apps/web/ /app/apps/web/
COPY proxy.ts ./
# Build the web app
WORKDIR /app/apps/web
RUN bun run build
# Return to root workdir
WORKDIR /app
# More forgiving health check during debugging
# More forgiving health check during debugging (router en 3000)
HEALTHCHECK --start-period=30s --interval=30s --timeout=3s --retries=3 \
CMD curl -f http://localhost:${PORT:-3007}/health || exit 0
CMD curl -f http://localhost:3000/health || exit 0
# Server runs on port from environment variable
EXPOSE ${PORT:-3007}
# Expose router port
EXPOSE 3000
# Declare volume for persistent data by default
VOLUME ["/app/data"]

@ -0,0 +1,44 @@
const BOT_ORIGIN = 'http://127.0.0.1:3007';
const WEB_ORIGIN = 'http://127.0.0.1:3008';
function shouldRouteToBot(pathname: string): boolean {
if (pathname === '/metrics' || pathname.startsWith('/metrics/')) return true;
if (pathname === '/webhook' || pathname.startsWith('/webhook/')) return true;
return false;
}
function buildForwardHeaders(req: Request): Headers {
const headers = new Headers(req.headers);
try {
const proto = headers.get('x-forwarded-proto') || 'https';
const fwdFor = headers.get('x-forwarded-for');
headers.set('x-forwarded-proto', proto);
headers.set('x-forwarded-for', fwdFor ? `${fwdFor}, 127.0.0.1` : '127.0.0.1');
} catch {}
return headers;
}
Bun.serve({
port: Number(process.env.PORT || process.env.ROUTER_PORT || 3000),
fetch: async (req) => {
const url = new URL(req.url);
const targetOrigin = shouldRouteToBot(url.pathname) ? BOT_ORIGIN : WEB_ORIGIN;
const targetUrl = targetOrigin + url.pathname + url.search;
const init: RequestInit = {
method: req.method,
headers: buildForwardHeaders(req),
body: req.method === 'GET' || req.method === 'HEAD' ? undefined : req.body,
redirect: 'manual',
};
try {
const res = await fetch(targetUrl, init);
// Devuelve la respuesta tal cual (incluye Set-Cookie, Location, etc.)
return res;
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
return new Response(`Proxy error: ${msg}\n`, { status: 502 });
}
},
});

@ -1,7 +1,18 @@
#!/bin/bash
set -euo pipefail
# Wait for server to be ready
# Arranca el bot en segundo plano (puerto 3007 por defecto)
BOT_PORT="${BOT_PORT:-3007}"
PORT="$BOT_PORT" bun run index.ts &
# Arranca la web (SvelteKit) en segundo plano en el puerto 3008
WEB_PORT="${WEB_PORT:-3008}"
pushd apps/web >/dev/null
PORT="$WEB_PORT" bun ./build/index.js &
popd >/dev/null
# Pequeña espera para evitar condiciones de carrera
sleep 1
# Start the main process
exec bun run index.ts
# Arranca el router en primer plano en el puerto 3000 (o $PORT si viene de CapRover)
exec bun proxy.ts

Loading…
Cancel
Save