Servidor de produccion
La producción de Zentto corre en un nodo Hetzner Cloud (centros de datos certificados ISO 27001) que aloja todo el ecosistema: el ERP (API + micro-frontends), los microservicios de plataforma (auth, payments, notify, cache, kyc, geo…), los verticales (hotel, medical, education, rental, tickets, inmobiliario…), la observabilidad (Loki + Grafana) y Vault. PostgreSQL corre en el host; todo lo demás en Docker.
Especificaciones (verificadas 2026-08-18)
| Propiedad | Valor |
|---|---|
| Proveedor | Hetzner Cloud (ISO 27001) — zentto-server |
| Plan | CX53 — 16 vCPU, 30 GB RAM, 300 GB SSD |
| IP pública | 178.104.56.185 |
| SO | Ubuntu 24.04 LTS |
| Base de datos | PostgreSQL 16 en el host (fuera de Docker), BD zentto_prod + BDs por servicio/tenant |
| Contenedores | ~70 en ejecución (ERP + microservicios + verticales + observabilidad) |
| Dominio | zentto.net (Cloudflare, wildcard *.zentto.net) |
Resiliencia y seguridad
- Cloudflare como capa perimetral: anycast, mitigación DDoS, TLS extremo a extremo, proxy ON en los registros HTTP.
- Firewall de borde Hetzner (
zentto-prod-edge): inbound permitido solo TCP 22/80/443 + ICMP (+ el puerto WireGuard del gateway dev); el resto se descarta en el borde, antes de llegar al servidor. UFW está inactivo en el host — el firewall real es el de Hetzner Cloud, gestionado por API. Un servicio nuevo con puerto público requiere abrirlo ahí (si no: timeout silencioso). - PostgreSQL endurecido:
listen_addressesrestringido a localhost + los gateways Docker (172.18/19/20.0.1); acceso solo desde las redes Docker víapg_hba.confconscram-sha-256. El puerto 5432 no es alcanzable desde internet. - Contenedores con reinicio automático y deploys solo por CI/CD; una versión defectuosa se revierte re-desplegando la imagen anterior de ghcr.io.
- Secretos en Vault (contenedor
zentto-vault, AppRole + KV v2): los servicios llevan solo el bootstrap AppRole en su env-file y leen el resto al arrancar. - Cookies httpOnly para autenticación, TOTP en el backoffice, RBAC, auditoría (ver Integridad y trazabilidad).
- Respaldos: automáticos por tenant a Hetzner Object Storage (ver Respaldo y retención).
Arquitectura de servicios
Internet
|
Cloudflare DNS + proxy (*.zentto.net)
|
Nginx (host, 80/443, SSL wildcard)
|
+-- app.zentto.net --> zentto-frontend (PM2, micro-apps Next.js)
+-- api.zentto.net --> zentto-api (:4000)
+-- auth.zentto.net --> zentto-auth
+-- pagos / notify / crm / pulse / kyc / geo / store / ...
+-- {vertical}.zentto.net --> {vertical}-frontend / -api
+-- {tenant}.zentto.net --> frontend + BD del tenant
+-- logs.zentto.net --> Grafana (Loki)
|
PostgreSQL 16 (host :5432) <-- containers via gateway Docker 172.x.0.1 El detalle del ecosistema (qué servicio vive en qué contenedor) está en Stack tecnológico; los puertos del ERP en Docker.
Nginx — Reverse proxy
Configuración en /etc/nginx/sites-available/zentto, gestionada desde el repo
zentto-infra (nunca editar a mano sin sincronizar). Puntos clave:
- HTTP redirige a HTTPS (
return 301). - Un
serverblock por subdominio; el wildcard atiende a los tenants. Cuidado conserver_nameduplicados: nginx toma el primero y sirve la app equivocada sin error. - CORS manejado en Nginx con flag
always(los headers llegan incluso en 502/500); los headers CORS del upstream se ocultan para evitar duplicados. - Preflight
OPTIONSrespondido directo sin pasar al backend. - Buffers ampliados (
proxy_buffer_size 64k) para las cookies de sesión.
SSL/TLS
Certificado wildcard *.zentto.net emitido con
certbot-dns-cloudflare (DNS-01), renovación automática
(scripts/certbot-wildcard.sh en zentto-infra). TLS 1.2/1.3.
Cloudflare DNS
| Tipo | Nombre | Valor | Proxy |
|---|---|---|---|
| A | zentto.net / www / api / app / auth / … | 178.104.56.185 | ON |
| A | *.zentto.net (wildcard tenants) | 178.104.56.185 | ON |
| CNAME | *dev (hostnames de desarrollo) | túnel Cloudflare del centro de datos dev | ON |
PostgreSQL desde Docker
- PG_HOST: el gateway de la red Docker del servicio —
172.18.0.1para la red principalzentto_zentto-net(hay servicios en 172.19/172.20). Nuncalocalhost. - pg_hba.conf:
host zentto_prod zentto_app 172.18.0.0/16 scram-sha-256(y equivalentes para las demás redes/BDs). - Si un servicio nuevo usa otra red Docker, su gateway debe agregarse al conf de
listen_addressesy reiniciar PostgreSQL (no basta reload).
docker restart NO relee el env-file. Tras cambiar
/opt/zentto/.env.* hay que recrear el contenedor (docker compose up -d --force-recreate
o el deploy de CI), no reiniciarlo.
Monitoreo y logs
La vía principal es Loki + Grafana (https://logs.zentto.net) — ver
Observabilidad. Para diagnóstico directo:
# Logs de contenedores
docker logs zentto-api --tail 100 -f
docker exec zentto-frontend pm2 status
# Nginx
tail -f /var/log/nginx/error.log
# PostgreSQL
systemctl status postgresql
journalctl -u postgresql --since "1 hour ago"
# Estado general
docker ps --format '{{.Names}}\t{{.Status}}' | sort
df -h / && docker system df Ambiente de desarrollo
Desde 2026-08-17 el ambiente dev completo no vive en Hetzner: corre en el
centro de datos local (Proxmox dellxeon, LXC dev) y se publica con un
túnel Cloudflare. Los ~47 contenedores dev que existían en Hetzner están detenidos como rollback.
Detalle completo: Centro de datos dev (dellxeon).