Compare commits

..

2 Commits

Author SHA1 Message Date
Suriyakumarvijayanayagam
2d1f8e4156 Remove the empty VITE_API_BASE_URL build arg - it overrode .env.production
The deployed bundle shipped with no API base URL, so every request fell back to
a relative /api/*, which the frontend's nginx forwards to a backend:8000 service
this deployment does not have.

The cause was this Dockerfile. Vite gives a real environment variable precedence
over its .env files, so `ARG VITE_API_BASE_URL=""` followed by `ENV
VITE_API_BASE_URL=$VITE_API_BASE_URL` did not leave the value unset - it set it
to an empty string and overrode .env.production. Nothing about the build says
so; it just quietly produces a bundle with no API host.

Reproduced directly: building with VITE_API_BASE_URL="" in the environment
yields a bundle with no API URL, and building with the variable unset bakes in
https://mcp.nearle.ai.in from .env.production.

The value now comes from .env.production alone. Point a build elsewhere by
editing that file or adding .env.local; both are read by Vite and neither can be
silently empty.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 13:00:37 +05:30
Suriyakumarvijayanayagam
0096008db5 Ship the API URL as .env.production - Dokploy was overwriting .env
The deployed bundle had no API base URL baked in at all, so the app fell back to
relative /api/* requests, which the frontend's nginx forwards to a backend:8000
service that does not exist in this deployment.

Same cause as the backend: Dokploy writes its own .env into the build context
from the service's Environment tab after cloning, and that tab is empty, so the
committed file was replaced by a zero-byte one. The checkout showed .env at 0
bytes, and grepping the running container's bundle for the API host returned
nothing.

Vite loads .env.production for production builds and it takes precedence over
.env, so the config now travels under that name and survives. No Dockerfile
change is needed - Vite resolves it natively - and the --build-arg stays
unnecessary.

Verified by writing an empty .env over the checkout, exactly as Dokploy does,
and building: https://mcp.nearle.ai.in is still inlined into the bundle.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 12:34:51 +05:30
3 changed files with 25 additions and 17 deletions

View File

@@ -1,5 +1,9 @@
# Committed on purpose - see .gitignore.
#
# Named .env.production, not .env: Dokploy overwrites .env in the build context
# from the service's Environment tab (empty when that tab is blank). Vite loads
# .env.production for production builds and it wins over .env, so this survives.
#
# Nothing here is a secret. VITE_API_BASE_URL is inlined into the public JS
# bundle at build time, so it is readable by anyone who opens the site; keeping
# it out of git protected nothing and only meant the value had to be remembered

15
.gitignore vendored
View File

@@ -12,15 +12,22 @@ dist
dist-ssr
*.local
# .env is committed here deliberately. It holds only VITE_API_BASE_URL, which
# Vite inlines into the public bundle anyway - it is visible to anyone who opens
# the site, so ignoring it protected nothing. Committing it means the deploy
# .env.production is committed deliberately. It holds only VITE_API_BASE_URL,
# which Vite inlines into the public bundle anyway - visible to anyone who opens
# the site - so ignoring it protected nothing, and committing it means the deploy
# does not depend on remembering a --build-arg.
#
# The name matters. Dokploy writes its own .env into the build context from the
# service's Environment tab after cloning, so a committed .env is silently
# replaced - with an empty file when that tab is blank, which is exactly what
# left the deployed bundle with no API URL at all. Vite loads .env.production
# for production builds and it takes precedence over .env, so this survives.
#
# Anything genuinely secret must NOT go in a VITE_-prefixed variable: it would
# be published in the bundle. Use .env.local (still ignored) for local
# overrides.
!.env
!.env.production
.env
.env.local
# Editor directories and files

View File

@@ -7,21 +7,18 @@ RUN npm ci
COPY . .
# Which origin the built app sends its API calls to.
# Which origin the built app calls comes from .env.production, committed next to
# this file, and Vite inlines it at build time.
#
# Vite inlines env vars at build time, so this MUST be a build arg - setting it
# on the running container has no effect, the value is already baked into the
# JS bundle.
# There is deliberately no ARG/ENV VITE_API_BASE_URL here. Vite gives a real
# environment variable precedence over its .env files, so declaring one with an
# empty default did not "leave it unset" - it actively set the value to an empty
# string and overrode .env.production. The build succeeded, the bundle shipped
# with no API base URL, and every request fell back to a relative /api/* that
# nginx forwards to a backend service this deployment does not have.
#
# docker build --build-arg VITE_API_BASE_URL=https://mcp.nearle.ai.in .
#
# Left empty by default, which keeps requests relative and same-origin so the
# nginx /api/* proxy below serves them. Set it when the API is on its own
# domain - and add this app's origin to the backend's API_CORS_ORIGINS, or the
# browser will block the responses.
ARG VITE_API_BASE_URL=""
ENV VITE_API_BASE_URL=$VITE_API_BASE_URL
# To point a build somewhere else, edit .env.production, or add .env.local
# (ignored by git) - both are read by Vite and neither is silently empty.
RUN npm run build
# ---- Serve stage ----