fix: move frontend off port 3000 and silence reverse-proxy panic logs (#568)

This commit is contained in:
Carlos Florêncio
2026-04-09 18:50:43 +01:00
committed by GitHub
parent ebefac814a
commit 7ad7736e07
9 changed files with 32 additions and 20 deletions
+1 -1
View File
@@ -118,4 +118,4 @@ EXPOSE 8080
# tini as PID 1 for signal handling; entrypoint handles privilege drop
ENTRYPOINT ["tini", "--", "docker-entrypoint.sh"]
CMD ["kandev", "start", "--backend-port", "8080", "--web-port", "3000", "--verbose"]
CMD ["kandev", "start", "--backend-port", "8080", "--web-port", "37429", "--verbose"]
+3 -3
View File
@@ -55,7 +55,7 @@ help:
@echo "Development Commands:"
@echo " dev Run backend + web via CLI (auto ports)"
@echo " dev-backend Run backend in development mode (port 8080)"
@echo " dev-web Run web app in development mode (port 3000)"
@echo " dev-web Run web app in development mode (port 37429)"
@echo " dev Note: Uses apps/cli launcher (auto ports)"
@echo ""
@echo "Production Commands:"
@@ -121,8 +121,8 @@ dev-backend:
.PHONY: dev-web
dev-web:
@echo "Starting web app on http://localhost:3000"
@cd $(APPS_DIR) && $(PNPM) --filter @kandev/web dev
@echo "Starting web app on http://localhost:37429"
@cd $(APPS_DIR) && PORT=37429 $(PNPM) --filter @kandev/web dev
#
# Build
+1 -1
View File
@@ -144,7 +144,7 @@ make dev
# Or run separately
make dev-backend # Backend on :8080
make dev-web # Frontend on :3000
make dev-web # Frontend on :37429
```
### Testing & Linting
+16 -4
View File
@@ -468,10 +468,9 @@ func registerRoutes(p routeParams) {
} else {
proxy := httputil.NewSingleHostReverseProxy(target)
proxy.FlushInterval = -1
// Custom error handler to prevent the default behavior of panicking
// with http.ErrAbortHandler when the upstream connection fails or the
// client disconnects. Without this, Gin's recovery middleware catches
// the panic and logs a full (harmless but noisy) stack trace.
// ErrorHandler catches upstream failures (e.g., connection refused)
// that occur before any response headers are written, returning a
// clean 502 instead of letting the default handler log an error.
proxy.ErrorHandler = func(w http.ResponseWriter, _ *http.Request, err error) {
p.log.Debug("Web proxy error", zap.Error(err))
w.WriteHeader(http.StatusBadGateway)
@@ -482,6 +481,19 @@ func registerRoutes(p routeParams) {
c.AbortWithStatus(http.StatusNotFound)
return
}
// httputil.ReverseProxy panics with http.ErrAbortHandler as an
// intentional stdlib signal when a streaming response is aborted
// (e.g., the client disconnects mid-body, or the upstream dies
// after response headers were already written). net/http.Server
// understands this sentinel panic and closes the connection
// quietly, but Gin's recovery middleware catches it first and
// logs a noisy stack trace. Swallow that specific panic here
// while letting any other panic bubble up to Gin's recovery.
defer func() {
if r := recover(); r != nil && r != http.ErrAbortHandler {
panic(r)
}
}()
proxy.ServeHTTP(c.Writer, c.Request)
})
p.log.Info("Web reverse proxy enabled", zap.String("target", p.webInternalURL))
+1 -1
View File
@@ -3,7 +3,7 @@ import path from "node:path";
// Default service ports (will auto-fallback if busy).
export const DEFAULT_BACKEND_PORT = 8080;
export const DEFAULT_WEB_PORT = 3000;
export const DEFAULT_WEB_PORT = 37429;
export const DEFAULT_AGENTCTL_PORT = 9999;
export const DEFAULT_MCP_PORT = 9090;
+1 -1
View File
@@ -14,7 +14,7 @@ vi.mock("./constants", () => ({
},
DATA_DIR: "/tmp/kandev-test-data",
DEFAULT_BACKEND_PORT: 8080,
DEFAULT_WEB_PORT: 3000,
DEFAULT_WEB_PORT: 37429,
DEFAULT_AGENTCTL_PORT: 9999,
HEALTH_TIMEOUT_MS_RELEASE: 15000,
RANDOM_PORT_MIN: 10000,
+1 -1
View File
@@ -96,7 +96,7 @@ export function buildWebEnv(options: WebEnvOptions): NodeJS.ProcessEnv {
...process.env,
// Server-side: full localhost URL for SSR fetches (Next.js SSR → Go backend)
KANDEV_API_BASE_URL: ports.backendUrl,
// Client-side: port injection for dev mode (browser on :3000, API on :8080).
// Client-side: port injection for dev mode (browser on web port, API on backend port).
// In production, the backend reverse-proxies Next.js so the client uses same-origin.
NEXT_PUBLIC_KANDEV_API_PORT: String(ports.backendPort),
PORT: String(ports.webPort),
+1 -1
View File
@@ -2,7 +2,7 @@ import type { NextConfig } from "next";
const defaultDevOrigins = [
"localhost",
"localhost:3000",
"localhost:37429",
"192.168.1.116", // Maintainer dev server
"100.105.155.17", // Maintainer dev server (Tailscale)
];
+7 -7
View File
@@ -50,7 +50,7 @@ npm install -g kandev
# Run the latest release (recommended for users)
npx kandev
# Opens the app at http://localhost:3000 (or next available port)
# Opens the app at http://localhost:37429 (or next available port)
```
## Commands
@@ -113,7 +113,7 @@ npx kandev start
|--------|-------------|---------|
| `--version <tag>` | Use a specific release version | `--version v0.1.0` |
| `--backend-port <port>` | Override backend port | `--backend-port 8080` |
| `--web-port <port>` | Override web port | `--web-port 3000` |
| `--web-port <port>` | Override web port | `--web-port 37429` |
| `--help`, `-h` | Show help | `--help` |
### Examples
@@ -126,7 +126,7 @@ npx kandev --version v0.1.0
npx kandev --backend-port 18080 --web-port 13000
# Dev mode with custom ports
npx kandev dev --backend-port 8080 --web-port 3000
npx kandev dev --backend-port 8080 --web-port 13000
```
## Port Selection
@@ -136,9 +136,9 @@ By default, the CLI automatically finds available ports:
| Service | Default Port | Fallback |
|---------|--------------|----------|
| Backend | 8080 | Auto-selects from 10000-60000 |
| Web | 3000 | Auto-selects from 10000-60000 |
| AgentCtl | 8081 | Auto-selects from 10000-60000 |
| MCP Server | 8082 | Auto-selects from 10000-60000 |
| Web | 37429 | Auto-selects from 10000-60000 |
| AgentCtl | 9999 | Auto-selects from 10000-60000 |
| MCP Server | 9090 | Auto-selects from 10000-60000 |
If the default port is in use, the CLI finds the next available port automatically.
@@ -186,7 +186,7 @@ See `make help` for all available commands.
The CLI automatically finds available ports. If you need a specific port:
```bash
npx kandev --backend-port 8080 --web-port 3000
npx kandev --backend-port 8080 --web-port 37429
```
### Backend Takes Too Long to Start