fix(web): resolve API and docs upstreams at runtime (#4840)

* fix(web): resolve upstream URLs at runtime

* fix(web): keep unconfigured upstreams same-origin

* fix(web): restore dev-only localhost fallbacks for API and docs upstreams

`next dev` on a developer machine now falls back to the conventional
http://localhost:8080 backend (honoring BACKEND_PORT) and
http://localhost:4000 docs origin when nothing is configured, so a bare
`pnpm dev:web` keeps proxying out of the box. Builds and the runtime
proxy keep the strict resolvers, so prebuilt images still leave unset
upstreams unproxied.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Naiyuan Qing <145280634+NevilleQingNY@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
苗大
2026-07-24 11:02:46 +08:00
committed by GitHub
parent 8d18d3a9ec
commit a90aa92d0c
17 changed files with 569 additions and 138 deletions

View File

@@ -138,18 +138,15 @@ spec:
name: http
{{- if .Values.frontend.compatibility.backendAlias }}
---
# DNS alias: the multica-web image bakes REMOTE_API_URL=http://backend:8080
# at build time, and the Next.js standalone build does not re-evaluate the
# rewrite destinations from runtime env. This ExternalName makes the bare
# host "backend" resolve to the backend Service inside the cluster, so the
# frontend's /api, /ws, /auth, and /uploads proxies work out of the box.
# DNS alias for legacy multica-web images that baked
# REMOTE_API_URL=http://backend:8080 at build time. Current images resolve
# frontend.config.remoteApiUrl at runtime and do not need this Service.
#
# The name is intentionally unprefixed ("backend", not "{{ .Release.Name }}-backend")
# because the baked-in host has no release prefix. As a result only ONE release
# of this chart can run per namespace, and the name may collide with a
# pre-existing Service/backend (see frontend.compatibility.backendAlias in
# values.yaml). Operators running a web image built with a patched
# REMOTE_API_URL can set that value to false to drop this Service entirely.
# values.yaml).
apiVersion: v1
kind: Service
metadata:

View File

@@ -1,4 +1,5 @@
{{- $frontendImageTag := default .Chart.AppVersion .Values.images.frontend.tag -}}
{{- $remoteApiUrl := default (printf "http://%s:8080" (include "multica.backend.fullname" .)) .Values.frontend.config.remoteApiUrl -}}
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -31,6 +32,20 @@ spec:
value: "0.0.0.0"
- name: PORT
value: "3000"
- name: REMOTE_API_URL
value: {{ $remoteApiUrl | quote }}
{{- if .Values.frontend.config.docsUrl }}
- name: DOCS_URL
value: {{ .Values.frontend.config.docsUrl | quote }}
{{- end }}
{{- if .Values.frontend.config.publicApiUrl }}
- name: NEXT_PUBLIC_API_URL
value: {{ .Values.frontend.config.publicApiUrl | quote }}
{{- end }}
{{- if .Values.frontend.config.publicWsUrl }}
- name: NEXT_PUBLIC_WS_URL
value: {{ .Values.frontend.config.publicWsUrl | quote }}
{{- end }}
resources:
{{- toYaml .Values.frontend.resources | nindent 12 }}
{{- with .Values.frontend.affinity }}

View File

@@ -144,23 +144,27 @@ backend:
# -----------------------------------------------------------------------------
# Frontend (Next.js standalone)
#
# The multica-web image bakes REMOTE_API_URL=http://backend:8080 at build time;
# the chart ships an ExternalName Service named "backend" so that bare host
# resolves to the in-cluster backend Service.
# -----------------------------------------------------------------------------
frontend:
replicas: 1
# Compatibility shim for the prebuilt multica-web image.
config:
# Backend origin used by the frontend runtime proxy for /api, /auth,
# /uploads, and /ws. Empty defaults to this release's backend Service.
remoteApiUrl: ""
# Optional docs origin used by the frontend runtime proxy for /docs.
docsUrl: ""
# Optional browser-visible split-origin overrides. Leave empty for the
# default same-origin frontend proxy.
publicApiUrl: ""
publicWsUrl: ""
# Compatibility shim for legacy multica-web images built before runtime
# URL rewrites. New images do not need this unprefixed Service.
compatibility:
# When true (default) the chart creates an ExternalName Service literally
# named "backend" so the REMOTE_API_URL=http://backend:8080 baked into the
# web image resolves in-cluster. Because that name is unprefixed, only ONE
# release of this chart can run per namespace, and it will collide with any
# pre-existing Service/backend (helm install then fails without
# --take-ownership). Set to false if you run a web image built with a
# patched REMOTE_API_URL and don't need the alias.
backendAlias: true
# When true the chart creates an ExternalName Service literally named
# "backend" for old images that baked REMOTE_API_URL=http://backend:8080.
# Because that name is unprefixed, only ONE such release can run per
# namespace. Keep false for current images.
backendAlias: false
resources:
requests:
cpu: 100m