Este es el checklist que quieres tener antes de abrir Odoo al mundo. No es teoría: es lo que evita el 80% de incidentes de arranque (auth, pools, websocket, colas, locks, logs, backups).
1) Red y exposición (capa “no te hackeen”)
Odoo NO está expuesto directo a Internet
http_interface = 127.0.0.1 (o red privada)
Solo el reverse proxy (Nginx/HAProxy) escucha en 443 (TLS)
Firewall:
443 abierto al mundo
8069/8072 cerrados al mundo (solo localhost o red interna)
6432 (PgBouncer) solo accesible desde Odoo/red interna
5432 (Postgres) solo accesible desde PgBouncer/bastión
2) Reverse proxy y WebSocket (el “clásico bug fantasma”)
/ → Odoo HTTP (8069)
/websocket/ → Odoo gevent (8072)
Headers correctos:
X-Forwarded-For
X-Forwarded-Proto
Host
proxy_mode = True en Odoo
Timeouts del proxy razonables (reportes PDF no son 5s)
3) Odoo: configuración mínima segura
admin_passwd fuerte y fuera del repo
list_db = False
dbfilter definido (si aplica multi-DB / multi-tenant)
addons_path separado (core vs custom)
logfile definido y con rotación (logrotate/journald)
4) Odoo: concurrencia y límites (para que no se “coma” el host)
workers dimensionados por CPU/RAM (no por fe)
max_cron_threads conservador (1–2) si no mediste aún
Límites configurados:
limit_time_cpu
limit_time_real
limit_memory_soft
limit_memory_hard
Si hay picos por crons: batching + evitar transacciones largas (plan de mitigación)
5) PgBouncer: pool correcto (y sin sorpresas)
pool_mode = transaction para Odoo web
default_pool_size calculado (y no “random”)
reserve_pool_size para picos cortos
max_client_conn suficiente para workers + picos
Si hay múltiples DBs: considera max_db_connections y límites por pool
6) Auth: usuarios, userlist y recargas
auth_type definido (idealmente scram-sha-256)
auth_file (userlist.txt) con formato correcto y permisos 0600
Si usas auth_user/auth_query: rol técnico y query/fn bien armada
Procedimiento de rotación:
editar userlist
RELOAD (o SIGHUP) sin downtime
7) TLS “si corresponde” (no siempre, pero cuando toca, toca bien)
Si Odoo↔PgBouncer cruzan redes no confiables: TLS habilitado
db_sslmode en Odoo (ideal verify-full si tienes CA/hostname bien)
Certificados con SAN correcto (hostname)
Plan de rotación de certs (caducidad monitoreada)
8) PostgreSQL: límites, timeouts y salud de DB
max_connections coherente con pools reales (PgBouncer)
Timeouts:
statement_timeout (según tu política)
lock_timeout
idle_in_transaction_session_timeout
Logs útiles:
log_lock_waits (si necesitas visibilidad de locks)
Autovacuum monitoreado (para que el rendimiento no se degrade con el tiempo)
9) Observabilidad mínima (sin esto, vuelas a ciegas)
PgBouncer
SHOW POOLS; monitoreado (cl_waiting, maxwait)
SHOW STATS; recolectado (TPS/latencia agregada)
Logs:
log_connections=1
log_disconnections=1
log_pooler_errors=1
Odoo
p95/p99 de endpoints clave (login, listados, write, reportes)
errores (timeouts, pool full, deadlocks) como métricas/alertas
duración de crons y solape (backlog)
Postgres
transacciones largas (xact_start)
sesiones esperando locks
top queries (si usas pg_stat_statements)
Infra
CPU, RAM, swap
I/O wait y latencia de disco
red (drops/retransmits)
file descriptors (especialmente PgBouncer)
10) Backups, restore y “día 2” (lo que define si sobrevives)
Backups automáticos verificados (no solo “existen”)
Restore probado en staging (RTO real, no teórico)
Plan de mantenimiento:
upgrade de Odoo
upgrade de Postgres
upgrade de PgBouncer
Documentación interna:
cómo ver cola (SHOW POOLS)
cómo recargar auth_file
qué hacer ante locks/transacciones largas
Cierre (la regla de oro)
Si solo haces 3 cosas para estar tranquilo:
Proxy + WebSocket bien ruteado
PgBouncer dimensionado con métricas (cl_waiting, maxwait)
Crons sin transacciones largas (batching)