diff --git a/AGENTS.md b/AGENTS.md index d6fab5b..ea27cbe 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -30,7 +30,10 @@ Environment: `backend/.env` (`PORT=5000`, `MONGO_URI=mongodb://127.0.0.1:27017/m `JWT_SECRET` — signs session tokens, `AUTH_TOKEN_TTL` — how long one lasts, default `7d`; see `.env.example`). Without `JWT_SECRET` the API warns and uses an insecure dev key. Frontend API URL comes from `NUXT_PUBLIC_API_BASE` -(default `http://localhost:5000`, read via `runtimeConfig.public.apiBase`). +(default `http://localhost:5000`, read via `runtimeConfig.public.apiBase`). The frontend image +builds it empty: the browser then calls `/api` on its own origin, which nginx routes to +`backend:5000`, while the Nuxt server's own (SSR) `/api` calls go through a `routeRules` proxy +aimed at `NUXT_API_PROXY_TARGET` (`http://backend:5000` baked in at image build). There is **no test suite, linter, or typecheck script** configured — don't invent commands. diff --git a/frontend/Dockerfile b/frontend/Dockerfile index bdb4081..4e35748 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -14,6 +14,12 @@ RUN npm install ARG CACHEBUST=1 COPY . . +# Production API wiring (baked into the build): +# - the browser calls /api on its own origin; nginx forwards that to backend:5000 +# - the Nuxt server (SSR) reaches the backend container by service name +ENV NUXT_PUBLIC_API_BASE= +ENV NUXT_API_PROXY_TARGET=http://backend:5000 + # Build the Nuxt app RUN npm run build diff --git a/frontend/README.md b/frontend/README.md index 0f10108..02debf5 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -61,6 +61,12 @@ Handy macros: `\R`, `\N`, `\Z`, `\Q`, `\C` for the number sets. | `backend/.env` | `PORT` | `5000` | API port | | `backend/.env` | `MONGO_URI` | `mongodb://127.0.0.1:27017/mathew` | Mongo connection | | `frontend` env | `NUXT_PUBLIC_API_BASE` | `http://localhost:5000` | Where the UI calls the API | +| `frontend` build | `NUXT_API_PROXY_TARGET` | `http://localhost:5000` | Where the Nuxt server's own (SSR) `/api` calls are forwarded | + +In Docker the frontend image builds with `NUXT_PUBLIC_API_BASE=` (empty): the browser calls +`/api` on its own origin and nginx routes it to `http://backend:5000` — the same hop answers +the Nuxt server's SSR calls, which the image points at the backend container via +`NUXT_API_PROXY_TARGET`. ## Editing tips diff --git a/frontend/nuxt.config.ts b/frontend/nuxt.config.ts index 3f1fe06..d118f38 100644 --- a/frontend/nuxt.config.ts +++ b/frontend/nuxt.config.ts @@ -39,11 +39,20 @@ export default defineNuxtConfig({ runtimeConfig: { public: { - // Override with NUXT_PUBLIC_API_BASE in production - apiBase: process.env.NUXT_PUBLIC_API_BASE || 'http://localhost:5000', + // Where the UI calls the API. The Docker image sets this to "" so the + // browser calls /api on its own origin and nginx routes it to the + // backend; dev keeps the absolute localhost address. + apiBase: process.env.NUXT_PUBLIC_API_BASE ?? 'http://localhost:5000', }, }, + // The Nuxt server's own API calls (SSR) are relative once apiBase is "", + // and land on this Nitro route, which forwards them to the backend. The + // Docker image bakes NUXT_API_PROXY_TARGET=http://backend:5000 in at build. + routeRules: { + '/api/**': { proxy: `${process.env.NUXT_API_PROXY_TARGET || 'http://localhost:5000'}/api/**` }, + }, + app: { head: { meta: [