Problem
NEXT_PUBLIC_* values are inlined into the browser bundle at Next.js build time, not read at runtime. The container-build workflow hardcodes the API URL when building the frontend image:
# .github/workflows/build_containers.yml
echo "NEXT_PUBLIC_API_URL=http://k8s-wn-01.cam.uchc.edu:30001" > .env
docker build ... --tag ghcr.io/virtualcell/vcell-ai-frontend:${TAG_NAME} ...
Consequences:
- The published
vcell-ai-frontend image always points the browser at that NodePort (k8s-wn-01.cam.uchc.edu:30001), regardless of where it's deployed.
- Setting
NEXT_PUBLIC_API_URL at runtime (e.g. the frontend-config ConfigMap from kustomize/config/<env>/frontend.env) has no effect — the value is already baked in.
- The kustomize overlays route the API via the ingress host (
vcell-ai[-dev].cam.uchc.edu/api), which the baked image ignores. So the k8s deployment and the image disagree.
Options
- Build arg per environment — make
NEXT_PUBLIC_API_URL a Docker ARG/build secret and build a separate frontend image per environment (CI passes the right value per tag/target).
- Resolve the API base URL at runtime — e.g. a server-rendered
/config endpoint, or a non-NEXT_PUBLIC_ server-side var proxied by the Next.js Node server, so a single image works everywhere.
Option 2 is preferred (one portable image), but is a larger frontend change.
Scope
Touches .github/workflows/build_containers.yml and frontend/Dockerfile (and possibly frontend runtime config code). Intentionally left out of the kustomize deployment PR (#69).
References
Problem
NEXT_PUBLIC_*values are inlined into the browser bundle at Next.js build time, not read at runtime. The container-build workflow hardcodes the API URL when building the frontend image:Consequences:
vcell-ai-frontendimage always points the browser at that NodePort (k8s-wn-01.cam.uchc.edu:30001), regardless of where it's deployed.NEXT_PUBLIC_API_URLat runtime (e.g. thefrontend-configConfigMap fromkustomize/config/<env>/frontend.env) has no effect — the value is already baked in.vcell-ai[-dev].cam.uchc.edu/api), which the baked image ignores. So the k8s deployment and the image disagree.Options
NEXT_PUBLIC_API_URLa DockerARG/build secret and build a separate frontend image per environment (CI passes the right value per tag/target)./configendpoint, or a non-NEXT_PUBLIC_server-side var proxied by the Next.js Node server, so a single image works everywhere.Option 2 is preferred (one portable image), but is a larger frontend change.
Scope
Touches
.github/workflows/build_containers.ymlandfrontend/Dockerfile(and possibly frontend runtime config code). Intentionally left out of the kustomize deployment PR (#69).References
kustomize/README.md→ "Known follow-up: frontend NEXT_PUBLIC_API_URL is baked at build time"