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.

Most problems with ProyectoDocker fall into a small number of categories: the database isn’t ready yet, a port is already in use on your machine, or images haven’t been pushed to Docker Hub. The first place to look is always the container logs — run docker compose logs <service> to see exactly what each service is doing.
This error appears in the backend logs when the backend container starts before MySQL is fully ready to accept connections. It is expected behavior.The backend uses a connectWithRetry() function that logs Error al conectar a MySQL, reintentando en 5 segundos... and then waits 5 seconds before trying again:
server.js
db.connect((err) => {
  isConnecting = false;

  if (err) {
    console.error('Error al conectar a MySQL, reintentando en 5 segundos...', err.message);
    setTimeout(connectWithRetry, 5000);
  } else {
    console.log('¡Conectado exitosamente a la base de datos MySQL!');
    db.query("SET NAMES utf8mb4;");
  }
});
The docker-compose.yml health check also delays the backend start until MySQL is ready, but the first few retries are still normal. Wait up to 45 seconds and watch the logs:
docker compose logs backend
Once you see ¡Conectado exitosamente a la base de datos MySQL!, the backend is healthy and the frontend will connect automatically. The backend will self-heal without any manual intervention.
This loading screen is the expected state from App.js while the backend is not yet reachable. When axios.get('http://localhost:4000/cv') fails, the frontend sets isRetrying to true and retries every 3 seconds:
App.js
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);
  });
The spinner and message “Estableciendo conexión con los servicios…” display as long as isRetrying is true and no data has loaded. This resolves on its own as soon as the backend is ready — no action is needed.If the spinner persists for more than a minute, check whether the backend is actually running and connected to the database:
docker compose logs backend
This is a UTF-8/Latin-1 encoding mismatch between MySQL and the Node.js mysql2 driver. The backend’s sanearTexto() function is designed to fix this automatically by reading the MySQL response bytes as binary and re-decoding them as UTF-8:
server.js
const sanearTexto = (texto) => {
  if (!texto) return texto;
  const buffer = Buffer.from(texto, 'binary');
  return buffer.toString('utf8');
};
If corrupted characters still appear after the backend is running, the most likely cause is that the database was initialized without the current init.sql, which sets the charset to utf8mb4 and collation to utf8mb4_spanish_ci. Perform a full reset to re-run the initialization script:
docker compose down -v
docker compose up -d --pull always
This destroys the mysql_data volume and recreates the database from init.sql on next startup.
If Docker Compose reports that a port is already bound, another process on your machine is using port 3000 (frontend), 4000 (backend), or 3306 (MySQL).First, bring down any existing ProyectoDocker containers:
docker compose down
If the conflict is on port 3306, a locally installed MySQL instance is likely running on your machine. Stop it before starting the stack. On macOS or Linux you can typically stop it with:
# macOS (Homebrew)
brew services stop mysql

# Linux (systemd)
sudo systemctl stop mysql
Then run docker compose up -d --pull always again.
If Docker Compose cannot pull images, check two things:1. You are logged into Docker Hub.
docker login
Enter your Docker Hub username and password (or access token) when prompted.2. The images have been pushed.The docker-compose.yml references docker.io/fullstack2026/perez-backend:v1 and docker.io/fullstack2026/perez-frontend:v1. If you are using your own Docker Hub account, you must first build and push the images under your own username (Step 3 and Step 4 in the Quickstart):
docker build --no-cache -t docker.io/<username>/perez-backend:v1 ./backend
docker push docker.io/<username>/perez-backend:v1

docker build --no-cache -t docker.io/<username>/perez-frontend:v1 ./frontend
docker push docker.io/<username>/perez-frontend:v1
Then update the image: fields in docker-compose.yml to match your username before running docker compose up -d --pull always.
The database service runs a health check every 5 seconds with up to 10 retries:
docker-compose.yml
healthcheck:
  test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-prootpassword"]
  interval: 5s
  timeout: 5s
  retries: 10
If the container stays in unhealthy state after 50 seconds, inspect the MySQL logs directly:
docker compose logs database
A common cause is a schema mismatch from a previous run. If you updated init.sql but ran docker compose up without first removing the old volume, MySQL skips re-running init.sql because the data directory already exists. Fix this with a full volume reset:
docker compose down -v
docker compose up -d --pull always
This removes the stale mysql_data volume so MySQL re-initializes from init.sql on next startup.

General debugging tips

When something isn’t working, these three commands cover the majority of diagnostic needs:
# Check the state of all containers (running, healthy, exited)
docker compose ps

# Read the full log output from a specific service
docker compose logs <service>
Replace <service> with database, backend, or frontend depending on which container you’re investigating. If you’re unable to identify the problem or want to guarantee a clean environment, a full reset restores the stack to its initial state:
docker compose down -v && docker compose up -d --pull always
This destroys all volumes (including the database), pulls the latest images from Docker Hub, and starts fresh. MySQL will re-run init.sql automatically on the next startup.

Build docs developers (and LLMs) love