Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/teofilobetancourt/Tradiciones-y-Sabores/llms.txt

Use this file to discover all available pages before exploring further.

Nginx sits at the front of the Tradiciones y Sabores stack, handling two distinct responsibilities: serving the compiled React single-page application as static files, and transparently forwarding every request that begins with /api/ to the FastAPI backend running on port 5000. This dual-role setup means the browser only ever talks to one origin (port 80), eliminating cross-origin issues entirely and avoiding the need for any CORS preflight on API calls made from the frontend bundle.

Docker Configuration — nginx.docker.conf

This file is copied into the Nginx container image at build time and becomes the active server block for the production Docker deployment:
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _;

    root /var/www/tradicionesysabores;
    index index.html;

    location /docs {
        proxy_pass         http://backend:5000/docs;
        proxy_http_version 1.1;
        proxy_set_header   Host $host;
    }

    location /openapi.json {
        proxy_pass         http://backend:5000/openapi.json;
        proxy_http_version 1.1;
        proxy_set_header   Host $host;
    }

    location /api/v1/ {
        proxy_pass         http://backend:5000/api/;
        proxy_http_version 1.1;
        proxy_set_header   Host              $host;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }

    location /api/ {
        proxy_pass         http://backend:5000;
        proxy_http_version 1.1;
        proxy_set_header   Host              $host;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Key Directives Explained

Static file root

root /var/www/tradicionesysabores;
index index.html;
The root directive points to the directory where the Vite production build is copied during the Docker image build. Every static asset—JavaScript bundles, CSS, images, and the index.html entry point—is served directly from this path by Nginx without any application-layer involvement.

SPA fallback with try_files

location / {
    try_files $uri $uri/ /index.html;
}
React Router handles navigation entirely in the browser. Without this directive, refreshing a deep URL like http://localhost/orders would cause Nginx to look for a real file at that path, find nothing, and return a 404. The try_files chain instructs Nginx to first look for a matching file ($uri), then a matching directory ($uri/), and finally fall back to serving index.html so React Router can take over and render the correct view.

API reverse proxy

location /api/v1/ {
    proxy_pass         http://backend:5000/api/;
    proxy_http_version 1.1;
    proxy_set_header   Host              $host;
    proxy_set_header   X-Real-IP         $remote_addr;
    proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
}

location /api/ {
    proxy_pass         http://backend:5000;
    ...
}
Requests to /api/v1/ are forwarded to http://backend:5000/api/, where backend resolves to the tradiciones_sabores_api container via Docker’s internal DNS. The path rewrite strips the /v1 prefix so the FastAPI router receives the paths it expects (e.g., /api/ordenes). The broader /api/ block catches utility paths like /api/docs and /api/debug and forwards them verbatim to the backend.

Swagger UI and OpenAPI schema

location /docs {
    proxy_pass http://backend:5000/docs;
    ...
}

location /openapi.json {
    proxy_pass http://backend:5000/openapi.json;
    ...
}
These two locations expose the FastAPI interactive documentation and its OpenAPI schema through port 80, so they are accessible without knowing the backend’s direct port.

nginx.conf vs nginx.docker.conf

Two Nginx configuration files exist in the repository, each targeting a different runtime environment:
Featurenginx.docker.conf (Docker)nginx.conf (Local / Bare-Metal)
Backend hostname in proxy_passbackend:5000 (Docker DNS)127.0.0.1:5000 (localhost loopback)
Proxy timeout headersNot setproxy_read_timeout 60s, proxy_connect_timeout 10s
Asset cachingNot configuredexpires 1y + Cache-Control: public, immutable on /assets/
Gzip compressionNot configuredEnabled for HTML, CSS, JS, JSON, SVG
Security headersNot setX-Frame-Options, X-Content-Type-Options, X-XSS-Protection
/api/docs aliasNot presentProxies /api/docshttp://127.0.0.1:5000/docs
In Docker, service discovery is handled by Docker’s internal network, so proxy_pass uses the service name backend. On a bare-metal server where both Nginx and Uvicorn run as host processes, proxy_pass targets 127.0.0.1.

Multi-Stage Frontend Dockerfile

The root Dockerfile builds the React application and packages it into a minimal Nginx image using two separate stages:
# Stage 1: Build React SPA
FROM node:20-alpine AS build

WORKDIR /app

COPY package*.json ./
RUN npm ci

ARG VITE_API_URL=""
ARG VITE_API_KEY=""
ENV VITE_API_URL=$VITE_API_URL
ENV VITE_API_KEY=$VITE_API_KEY

COPY . .
RUN npm run build

# Stage 2: Serve via Nginx
FROM nginx:alpine

COPY --from=build /app/dist /var/www/tradicionesysabores
COPY nginx.docker.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
Stage 1 — node:20-alpine AS build All Node.js tooling, node_modules, TypeScript source files, and Vite internals are present only in this intermediate layer. Running npm ci ensures a clean, reproducible install from package-lock.json. The VITE_API_URL and VITE_API_KEY build arguments let CI/CD pipelines inject environment-specific values at build time. npm run build produces an optimised static bundle in /app/dist. Stage 2 — nginx:alpine Only two things are copied into the final image: the compiled /app/dist output (now placed at /var/www/tradicionesysabores) and the nginx.docker.conf server block. Every Node.js binary, source file, and build dependency is discarded, resulting in a final image that is just Nginx plus static HTML/CSS/JS.
The multi-stage build produces a significantly smaller Docker image than a single-stage approach. The nginx:alpine base image is roughly 10 MB, and the compiled React bundle typically adds fewer than 5 MB—keeping the final frontend image under 20 MB and reducing the attack surface in production.

Build docs developers (and LLMs) love