From 9a73e95ae5b90c8f12a4752bab7c70e54af4edd8 Mon Sep 17 00:00:00 2001 From: Panchito Date: Thu, 20 Aug 2026 11:00:14 -0500 Subject: [PATCH] Dashboard Leads - version limpia para servidor (.env y config de despliegue restaurados) --- docker-compose.yml | 36 ++++++++++++++++++++++++++++++++++++ frontend/.dockerignore | 6 ++++++ frontend/Dockerfile | 20 ++++++++++++++++++++ frontend/nginx.conf | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 docker-compose.yml create mode 100644 frontend/.dockerignore create mode 100644 frontend/Dockerfile create mode 100644 frontend/nginx.conf diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..3d684ef --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,36 @@ +# ============================================================ +# Dashboard Leads - despliegue con Docker Compose (EasyPanel) +# +# backend : FastAPI + uvicorn en el puerto 8001 +# (lee sus credenciales de backend/.env, incluido en la imagen) +# frontend: build de Vite servido por nginx en el puerto 80 +# +# En EasyPanel, apunta los dominios a: +# api-leads.escueladerefrigeracion.lat -> backend : 8001 +# dashboard-leads.escueladerefrigeracion.lat -> frontend : 80 +# ============================================================ + +services: + backend: + build: + context: ./backend + dockerfile: Dockerfile + restart: unless-stopped + expose: + - "8001" + healthcheck: + test: ["CMD-SHELL", "python -c \"import urllib.request;urllib.request.urlopen('http://127.0.0.1:8001/api/health')\" || exit 1"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 60s + + frontend: + build: + context: ./frontend + dockerfile: Dockerfile + restart: unless-stopped + expose: + - "80" + depends_on: + - backend diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..2d2cd85 --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,6 @@ +node_modules +dist +.env.local +npm-debug.log* +Dockerfile +.dockerignore diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..3e0ed07 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,20 @@ +# ── Etapa 1: build del frontend con Vite ── +FROM node:20-alpine AS build + +WORKDIR /app + +COPY package.json package-lock.json* ./ +RUN npm ci --no-audit --no-fund || npm install --no-audit --no-fund + +COPY . . +RUN npm run build + +# ── Etapa 2: servir el build con nginx ── +FROM nginx:alpine + +COPY --from=build /app/dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/frontend/nginx.conf b/frontend/nginx.conf new file mode 100644 index 0000000..f47310c --- /dev/null +++ b/frontend/nginx.conf @@ -0,0 +1,37 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # Compresion + gzip on; + gzip_types text/plain text/css application/json application/javascript + text/xml application/xml application/xml+rss text/javascript + image/svg+xml; + gzip_min_length 1024; + + # Cache larga para los assets con hash en el nombre + location /assets/ { + expires 1y; + add_header Cache-Control "public, immutable"; + try_files $uri =404; + } + + # SPA: cualquier ruta desconocida devuelve index.html + location / { + try_files $uri $uri/ /index.html; + } + + # index.html nunca se cachea, para que los deploys se vean al instante + location = /index.html { + add_header Cache-Control "no-store, no-cache, must-revalidate"; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + internal; + } +}