Odoo · DevOps · Producción
Actualizar un módulo en producción da miedo, y con razón: un -u mal planificado puede dejar la base de datos a medias, romper una vista o tirar el servicio en horario comercial. Con un poco de disciplina se puede reducir ese riesgo a casi cero.
Antes de tocar nada
El backup no es opcional
Antes de cualquier -u en producción, hay que tener un dump reciente y verificado. No sirve un backup que nadie ha restaurado nunca: hay que probarlo en un entorno de staging con la misma versión de Odoo y PostgreSQL.
# Dump completo de la base de datos
pg_dump -Fc -f backup_pre_update_$(date +%Y%m%d_%H%M).dump mi_base_datos
# Restaurar en un entorno de prueba para validar
createdb mi_base_datos_staging
pg_restore -d mi_base_datos_staging backup_pre_update_20260707_0930.dump
pg_dump no incluye los adjuntos guardados en disco (filestore). Si el módulo toca attachments o reports, copia también /var/lib/odoo/.local/share/Odoo/filestore/<db>.
Staging primero, siempre
Reproducir la actualización antes de tocar producción
La secuencia correcta es: restaurar el backup en staging, aplicar la actualización ahí, revisar logs y comportamiento, y solo entonces repetir la misma operación en producción. Esto detecta migraciones de datos rotas, vistas con xpath que ya no encuentran su nodo o constraints nuevas que fallan contra datos existentes.
# En staging, con la copia restaurada
odoo-bin -d mi_base_datos_staging -u mi_modulo --stop-after-init
# Revisar el log en busca de ERROR o CRITICAL
grep -E "ERROR|CRITICAL" odoo.log
La decisión clave
-u vs desinstalar y reinstalar
No son intercambiables. -u ejecuta los scripts de migración y actualiza vistas/datos manteniendo los registros existentes. Desinstalar y reinstalar borra todo lo que dependa del módulo (incluyendo datos de usuario si hay ondelete='cascade' de por medio) y vuelve a cargar los datos demo/iniciales desde cero.
| Situación | Acción recomendada |
|---|---|
| Cambios en vistas, campos nuevos, lógica Python | -u mi_modulo |
| Cambio de campo incompatible (tipo, relación) | Script de migración + -u |
| Módulo corrupto o con datos de prueba a limpiar en un entorno no productivo | Desinstalar y reinstalar |
| Producción con datos reales del módulo | Nunca reinstalar; siempre -u con migración |
-u acompañado de scripts de migración cuando el cambio lo requiera.
Minimizar la ventana de corte
Reducir el downtime real
--stop-after-init: aplica la actualización y para el proceso, en vez de dejar el worker sirviendo peticiones a medio actualizar.- Balanceador o proxy delante de varios workers: sacar el nodo a actualizar del pool antes del
-uy devolverlo después. - Actualizar en horario de bajo tráfico, pero no confiar solo en eso: la validación previa en staging es lo que realmente evita sorpresas.
- Separar el
-ude los reinicios de workers: primero se actualiza el esquema con un proceso dedicado, luego se reinician los workers de servicio.
# Actualización con corte controlado detrás de un proxy
systemctl stop odoo-worker@2 # sacar un nodo del pool
odoo-bin -d produccion -u mi_modulo --stop-after-init
systemctl start odoo-worker@2 # reincorporarlo ya actualizado
Cuando algo sale mal
Plan de rollback
El rollback de una actualización de Odoo casi nunca es "deshacer el commit": el esquema de la base de datos ya ha cambiado. Por eso el plan de rollback real es restaurar el backup pre-actualización (base de datos + filestore) y volver a desplegar el código de la versión anterior del módulo.
# Rollback completo
systemctl stop odoo
dropdb produccion
createdb produccion
pg_restore -d produccion backup_pre_update_20260707_0930.dump
git -C /opt/odoo/custom-addons checkout v1.4.2 # versión anterior del módulo
systemctl start odoo
Resumen
Actualizar sin sustos no depende de suerte: depende de tener un backup probado, reproducir el -u en staging, saber cuándo NO reinstalar, minimizar la ventana con --stop-after-init y tener un plan de rollback documentado antes de empezar, no improvisado a mitad de incidente.