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.

ProyectoDocker uses a three-tier Docker Compose architecture made up of a React frontend, a Node.js/Express backend, and a MySQL 8.0 database. Each tier runs in its own container, and Docker Compose coordinates how they start, communicate, and share data. Understanding how these services fit together helps you run, troubleshoot, and extend the project.

Service overview

The three services are defined in docker-compose.yml:
  • database — MySQL 8.0 container (cv_database), seeded from database/init.sql at first boot
  • backend — Node.js/Express API container (cv_backend), exposes a single /cv endpoint
  • frontend — Nginx container (cv_frontend) that serves the compiled React app
services:
  database:
    image: mysql:8.0
    container_name: cv_database

  backend:
    image: docker.io/fullstack2026/perez-backend:v1
    container_name: cv_backend

  frontend:
    image: docker.io/fullstack2026/perez-frontend:v1
    container_name: cv_frontend

The cv_network bridge network

All three services join a single user-defined bridge network called cv_network:
networks:
  cv_network:
    driver: bridge
Docker’s embedded DNS resolves each container by its service name, not by IP address. This means the backend can reach the database using the hostname database — exactly as configured in backend/server.js:
db = mysql.createConnection({
  host: 'database',
  user: 'root',
  password: 'rootpassword',
  database: 'cv_db',
  charset: 'utf8mb4'
});
Service-name DNS resolution only works between containers that share the same Docker network. All three services declare networks: - cv_network, so they can all reach each other by name.

Startup ordering

Docker Compose starts the services in dependency order to prevent the backend from crashing before the database is ready to accept connections. 1. database starts first and runs a health check to confirm MySQL is accepting connections:
healthcheck:
  test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-prootpassword"]
  interval: 5s
  timeout: 5s
  retries: 10
Compose polls every 5 seconds and allows up to 10 retries before marking the container as unhealthy. 2. backend waits for database to be healthy using the service_healthy condition:
backend:
  depends_on:
    database:
      condition: service_healthy
This prevents the backend process from starting — and attempting to connect — until MySQL is fully initialized and responding to pings. 3. frontend starts after backend using a simple dependency (no health check required):
frontend:
  depends_on:
    - backend
The frontend container itself does not poll the backend at startup. The React app retries the GET http://localhost:4000/cv request in the browser every 3 seconds until the backend responds successfully.

Persistent storage with mysql_data

MySQL data is stored in a named volume so it survives container restarts and re-creations:
database:
  volumes:
    - mysql_data:/var/lib/mysql
    - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql

volumes:
  mysql_data:
The mysql_data volume maps to /var/lib/mysql inside the container — MySQL’s default data directory. The init.sql file is mounted into /docker-entrypoint-initdb.d/, which MySQL runs automatically the first time the container starts with an empty data directory. Subsequent starts skip the initialization script because the volume already contains the database files.
To reset the database to its initial state, you must remove the named volume: docker compose down -v. This deletes all data and forces re-initialization on the next docker compose up.

Port mappings

Each service exposes a single port, mapped identically from host to container:
ServiceHost portContainer portProtocol
frontend30003000HTTP
backend40004000HTTP
database33063306TCP
database:
  ports:
    - "3306:3306"

backend:
  ports:
    - "4000:4000"

frontend:
  ports:
    - "3000:3000"
After running docker compose up, you can access the frontend at http://localhost:3000 and the backend API directly at http://localhost:4000/cv.

Restart policy

The database and backend services both declare restart: always, which instructs Docker to automatically restart them if they exit for any reason — including an unexpected crash or a host reboot.
database:
  restart: always

backend:
  restart: always
The frontend service does not declare a restart policy, so it starts once and remains in its final state if the Nginx process exits.
The frontend React app calls http://localhost:4000/cv from the browser, not from inside Docker. This means port 4000 must be published to the host for the frontend to work — even though both containers are on cv_network.

Database health check details

The health check on the database service uses mysqladmin ping to verify that MySQL is ready to accept connections:
healthcheck:
  test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-prootpassword"]
  interval: 5s
  timeout: 5s
  retries: 10
ParameterValueMeaning
interval5sHow often Compose runs the check
timeout5sHow long to wait before counting a check as failed
retries10Failed checks before the container is marked unhealthy
With these settings, Compose will wait up to 50 seconds (10 retries × 5s interval) for MySQL to become healthy before allowing the backend to start. If the database never becomes healthy, the backend container will not start.

Build docs developers (and LLMs) love