Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/jperez77775/ProyectoDocker/llms.txt

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

The frontend service renders the CV as a web page in the browser. It is a React 18 single-page application that fetches data from the backend API and displays a profile photo, name, city, and education history. In production the compiled output is served by Nginx, which is configured to listen on port 3000 instead of the default port 80.

Technology stack

ComponentVersion
React18.2.x
axios1.6.x
react-scripts5.0.1
Nginx1.27 (Alpine)
The service listens on port 3000, which is mapped directly to port 3000 on the host in docker-compose.yml.

What it renders

Once the backend responds successfully, the app renders a CV page with:
  • A circular profile photo loaded from the foto URL in the API response
  • The person’s full name (nombre + apellido) as a heading
  • Their city (ciudad) below the name
  • A bulleted education list (formacion) with degree title, institution, and year for each entry

Auto-retry behavior

The cargarDatos() function is called inside a useEffect hook on mount. It sends a GET request to http://localhost:4000/cv. If the request fails — for example because the backend container is still starting — it sets isRetrying to true and schedules another attempt in 3 seconds. This loop continues until the backend responds successfully.
src/App.js
useEffect(() => {
  let timer;

  const cargarDatos = () => {
    axios.get('http://localhost:4000/cv')
      .then(response => {
        setCvData(response.data);
        setIsRetrying(false);
      })
      .catch(err => {
        console.log("El backend aún no está listo, reintentando en 3 segundos...", err);
        setIsRetrying(true);
        timer = setTimeout(cargarDatos, 3000);
      });
  };

  cargarDatos();

  return () => clearTimeout(timer);
}, []);
The clearTimeout in the cleanup function prevents a stale timer from firing after the component unmounts.

Loading states

The app has three distinct visual states:
StateConditionWhat the user sees
Initial loading!cvData and !isRetryingPlain text: “Iniciando aplicación…”
Retry / waitingisRetrying and !cvDataSpinning circle with a message explaining that Docker services are synchronizing
SuccesscvData is setFull CV page with photo, name, city, and education list
The retry state gives users clear feedback that the app is waiting for infrastructure to become ready, rather than appearing broken.

Multi-stage Dockerfile

The image uses a two-stage build. Stage 1 compiles the React app using Node 20. Stage 2 copies only the compiled output into a fresh Nginx image, keeping the final image small by discarding the Node runtime and node_modules.
Dockerfile
# Stage 1: build
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Stage 2: production server
FROM nginx:1.27-alpine

RUN rm -rf /usr/share/nginx/html/*

COPY --from=build /app/build /usr/share/nginx/html

RUN sed -i 's/listen  *80;/listen 3000;/g' /etc/nginx/conf.d/default.conf

EXPOSE 3000
CMD ["nginx", "-g", "daemon off;"]
The sed command in stage 2 rewrites Nginx’s default configuration file, replacing the listen 80; directive with listen 3000;. This is necessary because docker-compose.yml maps host port 3000 to container port 3000, and the ports must match.
To inspect Nginx access logs and debug request routing, run docker compose logs frontend. Nginx writes both access and error logs to stdout/stderr so they appear in the Compose log stream.

Build docs developers (and LLMs) love