Installation
Instalar en un servidor Windows de red local
Ejecuta QuoteNode con Docker Desktop en un PC Windows dentro de una red de oficina.
Instalar en un servidor Windows de red local
Usa esta ruta cuando un PC Windows en la oficina deba alojar QuoteNode para usuarios en la misma red local.
Cuándo usarlo
- El equipo de ventas trabaja dentro de una misma red LAN de oficina.
- Los clientes no necesitan abrir enlaces de oferta desde internet pública.
- Quieres una beta interna sin gestionar un VPS público.
Qué no funcionará
- Los enlaces públicos de oferta y de notificación funcionarán solo para dispositivos en la misma LAN o VPN. Los clientes externos no pueden abrir una dirección de red local privada.
- Los mensajes de correo pueden enviarse si SMTP está configurado, pero los enlaces dentro siguen apuntando a la URL de la LAN.
- El modo suspensión de Windows, los reinicios o las actualizaciones de Docker Desktop pueden interrumpir el servicio.
Requisitos previos
- Docker Desktop con Compose v2 habilitado.
- Dirección IP de red local estable o reserva DHCP para el host Windows.
- Al menos 2 GB de RAM disponibles y 10 GB de espacio libre en disco.
- Ubicación de backup regular fuera del volumen de Docker.
Comprueba en PowerShell o Símbolo del sistema:
docker --version # Should show 24.0+
docker compose version # Should show v2.x
Paso 1 — Crear un directorio de proyecto
mkdir quotenode
cd quotenode
Paso 2 — Crear el archivo de configuración
Crea un archivo llamado .env en el directorio del proyecto. Reemplaza 192.168.1.50 con la IP real del host Windows (o un nombre DNS interno como quotenode.local):
# Database
DB_URL=jdbc:postgresql://postgres:5432/quotenode
DB_USERNAME=quotenode
DB_PASSWORD=change-me-to-something-random-32-chars
DB_NAME=quotenode
# ============================================================
# SECURITY SECRETS — UNIQUE to this installation.
# SAVE THIS FILE and keep a secure backup.
# ============================================================
DB_ENCRYPTION_KEY=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
TIMING_TOKEN_SECRET=change-me-timing-secret-min-32-chars
PUBLIC_LINK_PASSWORD_SESSION_SECRET=change-me-session-secret-min-32
# LAN URL — replace with your PC's IP or internal DNS name
CORS_ALLOWED_ORIGINS=http://192.168.1.50
DOMAIN=192.168.1.50
# La IP del cliente se detecta automáticamente tras proxies internos y CDNs (incluido Cloudflare) — déjalo vacío.
# Defínelo solo para un proxy inusual cuyo par de transporte sea una dirección PÚBLICA a confiar (IP/CIDR o nombre de host).
SECURITY_TRUSTED_PROXIES=
# Application
LOG_LEVEL=INFO
SPRING_PROFILES_ACTIVE=prod
Guarda tu archivo
.envinmediatamente. Guarda una copia fuera de este PC. Si pierdesDB_ENCRYPTION_KEY, los campos cifrados quedan permanentemente ilegibles.
Paso 3 — Crear el archivo Docker Compose
Crea un archivo llamado docker-compose.yml:
services:
postgres:
image: postgres:18-alpine
cpus: 4.0
mem_limit: 512m
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_PASSWORD: ${DB_PASSWORD}
PGDATA: /var/lib/postgresql/data # required for the postgres:18 image
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME}"]
interval: 10s
timeout: 5s
retries: 10
restart: unless-stopped
gotenberg:
image: gotenberg/gotenberg:8
cpus: 2.0
mem_limit: 448m
environment:
LOG_LEVEL: info
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:3000/health"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
backend:
image: ghcr.io/lesisty7/quotenode/quotenode-api:latest
cpus: 4.0
mem_limit: 1792m
depends_on:
postgres: { condition: service_healthy }
gotenberg: { condition: service_healthy }
env_file: .env
environment:
SPRING_PROFILES_ACTIVE: prod
JOBS_MODE: web
PDF_ENABLED: "true"
PDF_GOTENBERG_URL: http://gotenberg:3000
volumes:
- backend_uploads:/app/data/uploads
- backend_pdfs:/app/data/pdfs
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"]
interval: 15s
timeout: 10s
retries: 5
start_period: 45s
restart: unless-stopped
frontend:
image: ghcr.io/lesisty7/quotenode/quotenode-frontend:latest
cpus: 2.0
mem_limit: 192m
depends_on:
backend: { condition: service_healthy }
ports:
- "80:80"
- "443:443"
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:80/"]
interval: 15s
timeout: 5s
retries: 3
restart: unless-stopped
volumes:
postgres_data:
backend_uploads:
backend_pdfs:
Paso 4 — Iniciar QuoteNode
docker compose up -d
Docker descargará las imágenes al primer arranque. Observa el inicio:
docker compose logs -f backend
Espera hasta ver Started QuoteNodeApplication.
Paso 5 — Abrir QuoteNode
Navega a http://192.168.1.50 (o la dirección de tu PC) desde cualquier dispositivo en la red local.
Credenciales de acceso por defecto:
| Campo | Valor |
|---|---|
[email protected] | |
| Contraseña | Admin123! |
Cambia la contraseña por defecto inmediatamente tras iniciar sesión.
Firewall de Windows
- Permitir TCP entrante en el puerto 80 para acceso HTTP desde la LAN.
- Permitir TCP entrante en el puerto 443 solo si configuras HTTPS.
- No exponer PostgreSQL a la LAN a menos que tengas una necesidad administrativa específica.
- Mantener Docker Desktop ejecutándose bajo una cuenta y política de inicio apropiadas para tu oficina.
¿Qué está ejecutándose?
| Contenedor | Qué hace | Uso de RAM |
|---|---|---|
postgres | Almacena todos tus datos | ~256 MB |
backend | Servidor API Java, lógica de negocio | ~512 MB – 1,5 GB |
gotenberg | Convierte HTML a PDF (basado en Chromium) | ~200 MB |
frontend | Sirve la interfaz web + reverse proxy | ~20 MB |
Total: aproximadamente 1,5 – 2,5 GB de RAM.
Comandos habituales
# Check service status
docker compose ps
# View logs
docker compose logs -f backend
# Stop QuoteNode
docker compose down
# Update to the latest version
docker compose pull && docker compose up -d
Mantener seguros tus secretos
| Secreto | Qué protege | Si se pierde |
|---|---|---|
DB_PASSWORD | Acceso a la base de datos | Recuperable — reiniciar vía herramientas de administración PostgreSQL |
DB_ENCRYPTION_KEY | Códigos MFA, contraseña SMTP, clave API FX, campos PII | Permanentemente ilegible |
TIMING_TOKEN_SECRET | Tokens anti-timing-attack | Regenerar — los usuarios se re-autentican |
PUBLIC_LINK_PASSWORD_SESSION_SECRET | Sesiones de enlaces públicos | Regenerar — las sesiones activas expiran |
El secreto crítico es
DB_ENCRYPTION_KEY. Guarda copias de.envfuera de este PC. Ver Solución de problemas de instalación para los pasos de recuperación.
Siguientes pasos recomendados
- Configura backups y prueba una restauración.
- Usa Solución de problemas de instalación para problemas de CORS o enlaces.
- Migra a servidor público Ubuntu o Coolify antes de enviar enlaces públicos a clientes externos.