Servidor de produccion
La infraestructura de produccion corre en un servidor dedicado Hetzner con Docker, Nginx y PostgreSQL en el host.
Especificaciones
| Propiedad | Valor |
|---|---|
| Proveedor | Hetzner Cloud |
| Plan | CX33 (4 vCPU, 8 GB RAM, 80 GB SSD) |
| IP publica | 178.104.56.185 |
| SO | Ubuntu 22.04 LTS |
| Dominio | zentto.net (Cloudflare) |
Arquitectura de servicios
Internet
|
Cloudflare DNS (zentto.net, api.zentto.net)
|
Nginx (host, puertos 80/443)
|
+-- app.zentto.net --> Docker: zentto-frontend (PM2, puertos 3000-3014)
+-- api.zentto.net --> Docker: zentto-api (puerto 4000)
|
PostgreSQL (host, puerto 5432, DB: zentto_prod) Nginx — Reverse proxy
La configuracion esta en /etc/nginx/sites-available/zentto (referencia: nginx/zentto.conf del repo). Puntos clave:
- HTTP redirige a HTTPS (
return 301) app.zentto.netenruta al shell (3000) por defecto; sub-apps como/pos,/ventas,/restaurantevan a sus puertos especificosapi.zentto.netenruta al puerto 4000- CORS manejado en Nginx con flag
alwayspara que incluso respuestas de error lleven los headers - Preflight
OPTIONSrespondido directamente sin pasar al backend - Headers CORS del upstream (Express) se ocultan para evitar duplicados
# Buffers grandes para JWT (auth.js divide sesion en multiples cookies)
proxy_buffer_size 64k;
proxy_buffers 8 64k;
proxy_busy_buffers_size 128k; SSL/TLS — Let's Encrypt
Certificados gestionados con Certbot. Cubren zentto.net, www.zentto.net y api.zentto.net.
# Emision/renovacion del certificado
certbot --nginx -d zentto.net -d www.zentto.net -d api.zentto.net
# Verificar renovacion automatica
certbot renew --dry-run Protocolos habilitados: TLSv1.2 y TLSv1.3 con ssl_prefer_server_ciphers on.
Cloudflare DNS
Los registros DNS apuntan al servidor. El proxy de Cloudflare esta ON para HTTP y OFF para SSH.
| Tipo | Nombre | Valor | Proxy |
|---|---|---|---|
| A | zentto.net | 178.104.56.185 | ON |
| A | www | 178.104.56.185 | ON |
| A | api | 178.104.56.185 | ON |
| A | app | 178.104.56.185 | ON |
Firewall (UFW)
# Reglas esenciales
ufw allow 22/tcp # SSH
ufw allow 80/tcp # HTTP (redirect)
ufw allow 443/tcp # HTTPS
ufw allow from 172.18.0.0/16 to any port 5432 # Docker -> PostgreSQL La regla de iptables para DOCKER-USER se persiste en /etc/ufw/after.rules para sobrevivir reinicios.
PostgreSQL desde Docker
PostgreSQL corre en el host (no en Docker). Los contenedores acceden via el gateway de la red Docker:
- PG_HOST:
172.18.0.1(gateway Docker, nuncalocalhost) - pg_hba.conf:
host zentto_prod zentto_app 172.18.0.0/16 scram-sha-256 - Base de datos:
zentto_prod, usuariozentto_app
Monitoreo y logs
# Logs de contenedores Docker
docker logs zentto-api --tail 100 -f
docker logs zentto-frontend --tail 100 -f
# PM2 dentro del contenedor frontend
docker exec zentto-frontend pm2 status
docker exec zentto-frontend pm2 logs shell --lines 50
# Logs de Nginx
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
# Estado de PostgreSQL
systemctl status postgresql
journalctl -u postgresql --since "1 hour ago" Setup inicial del servidor
Para un servidor nuevo, ejecutar el script de setup:
bash <(curl -sSL https://raw.githubusercontent.com/zentto-erp/zentto-web/main/scripts/server-setup.sh) Este script instala Docker, Nginx, Certbot, crea la red Docker y los volumenes necesarios.