Odoo es un ERP de código abierto escrito en Python que reúne en una sola aplicación CRM, ventas, facturación, inventario, contabilidad y muchos otros módulos. En este tutorial instalarás Odoo 19 Community en Ubuntu 24.04 desde el repositorio oficial de Odoo, con PostgreSQL en el mismo servidor, configurarás el modo multiproceso y lo publicarás detrás de Nginx con HTTPS. Al terminar tendrás una base de datos de empresa lista para instalar aplicaciones y un sistema de copias de seguridad.

Requisitos previos

Para seguir esta guía necesitas:

  • Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 2 vCPU, 4 GB de RAM y 20 GB de disco. El paquete de Odoo 19 está construido para Ubuntu 24.04.
  • Un usuario no root con privilegios sudo.
  • Un dominio o subdominio (en esta guía, odoo.example.com) con un registro DNS A que apunte a la IP del servidor. Sustituye odoo.example.com por tu dominio en todos los pasos.
  • Los puertos 80 y 443 abiertos. El puerto de Odoo (8069) no debe quedar expuesto a Internet.

Paso 1: Instalar PostgreSQL

El paquete de Odoo espera un servidor PostgreSQL en la misma máquina y, al instalarse, crea en él un rol odoo con permiso para crear bases de datos. Instala PostgreSQL primero:

sudo apt update
sudo apt install -y postgresql

Comprueba que el servicio está activo:

sudo -u postgres psql -c "SELECT version();"
                                                    version
----------------------------------------------------------------------------------------------------------------
 PostgreSQL 16.10 (Ubuntu 16.10-0ubuntu0.24.04.1) on x86_64-pc-linux-gnu, compiled by gcc ...
(1 row)

Paso 2: Instalar wkhtmltopdf

Odoo genera facturas, presupuestos y demás informes PDF con wkhtmltopdf. La versión de los repositorios de Ubuntu no tiene el parche de Qt que Odoo necesita para cabeceras y pies de página, así que instala la 0.12.6.1 del proyecto wkhtmltopdf, que es la que recomienda Odoo:

cd /tmp
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.jammy_amd64.deb
sudo apt install -y ./wkhtmltox_0.12.6.1-3.jammy_amd64.deb

Es el paquete construido para Ubuntu 22.04, pero se instala sin problemas en 24.04 y apt resuelve sus dependencias. En servidores ARM64 descarga wkhtmltox_0.12.6.1-3.jammy_arm64.deb de la misma publicación.

Comprueba la versión:

wkhtmltopdf --version
wkhtmltopdf 0.12.6.1 (with patched qt)

Paso 3: Añadir el repositorio de Odoo e instalar Odoo

Odoo publica paquetes Community para Debian y Ubuntu en nightly.odoo.com. Descarga la clave del repositorio en /etc/apt/keyrings:

sudo install -m 0755 -d /etc/apt/keyrings
wget -qO- https://nightly.odoo.com/odoo.key | sudo gpg --dearmor -o /etc/apt/keyrings/odoo-archive-keyring.gpg

Añade el repositorio de la versión 19.0:

echo 'deb [signed-by=/etc/apt/keyrings/odoo-archive-keyring.gpg] https://nightly.odoo.com/19.0/nightly/deb/ ./' | sudo tee /etc/apt/sources.list.d/odoo.list

Instala Odoo. El paquete arrastra todas las dependencias de Python desde los repositorios de Ubuntu, sin pip:

sudo apt update
sudo apt install -y odoo

La instalación crea el usuario de sistema odoo, el archivo de configuración /etc/odoo/odoo.conf, el registro en /var/log/odoo/odoo-server.log y el servicio odoo, que queda activo. Compruébalo:

sudo systemctl status odoo
● odoo.service - Odoo Open Source ERP and CRM
     Loaded: loaded (/usr/lib/systemd/system/odoo.service; enabled; preset: enabled)
     Active: active (running) since Fri 2026-09-25 10:05:31 UTC; 12s ago

Y que responde en el puerto 8069:

curl -sI http://127.0.0.1:8069/web/database/selector | head -n 1
HTTP/1.1 200 OK

Paso 4: Configurar Odoo para producción

Edita el archivo de configuración:

sudo nano /etc/odoo/odoo.conf

Sustituye su contenido por este:

[options]
; Contraseña maestra del gestor de bases de datos
admin_passwd = your_master_password
db_host = False
db_port = False
db_user = odoo
db_password = False
default_productivity_apps = True

; Escuchar solo en local: el acceso externo pasa por Nginx
http_interface = 127.0.0.1
proxy_mode = True

; Modo multiproceso
workers = 4
max_cron_threads = 1
gevent_port = 8072

Qué hace cada bloque:

  • admin_passwd es la contraseña maestra, que permite crear, copiar, restaurar y borrar bases de datos desde el navegador. Por defecto es admin, así que cámbiala por una contraseña larga y aleatoria antes de exponer Odoo. Puedes generar una con openssl rand -base64 24.
  • http_interface = 127.0.0.1 evita que el puerto 8069 sea accesible desde fuera.
  • proxy_mode = True hace que Odoo confíe en las cabeceras X-Forwarded-* de Nginx para conocer el dominio, el esquema HTTPS y la IP real del cliente.
  • workers activa el modo multiproceso. Odoo recomienda como punto de partida (núcleos x 2) + 1 workers HTTP y aproximadamente 1 GB de RAM por cada 6 workers; con 2 vCPU y 4 GB, 4 workers es un valor razonable. Con workers activos, las conexiones websocket (chat, notificaciones en tiempo real) las atiende un proceso aparte en gevent_port.

db_user = odoo con db_host = False usa la conexión por socket local con el rol odoo que creó el paquete, sin contraseña de base de datos.

Reinicia el servicio y comprueba que ahora escucha en los dos puertos locales:

sudo systemctl restart odoo
sudo ss -tlnp | grep -E ':(8069|8072)'
LISTEN 0      128        127.0.0.1:8069       0.0.0.0:*    users:(("odoo",pid=4121,fd=4))
LISTEN 0      128        127.0.0.1:8072       0.0.0.0:*    users:(("odoo",pid=4130,fd=5))

Si el servicio no arranca, revisa el final del registro:

sudo tail -n 30 /var/log/odoo/odoo-server.log

Paso 5: Configurar Nginx como proxy inverso

Instala Nginx:

sudo apt install -y nginx

Crea el bloque de servidor de Odoo:

sudo nano /etc/nginx/sites-available/odoo
upstream odoo {
    server 127.0.0.1:8069;
}

upstream odoochat {
    server 127.0.0.1:8072;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;
    listen [::]:80;
    server_name odoo.example.com;

    client_max_body_size 100M;
    proxy_read_timeout 720s;
    proxy_connect_timeout 720s;
    proxy_send_timeout 720s;

    access_log /var/log/nginx/odoo.access.log;
    error_log /var/log/nginx/odoo.error.log;

    # Websocket: al proceso gevent
    location /websocket {
        proxy_pass http://odoochat;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # Resto de peticiones: a los workers HTTP
    location / {
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_redirect off;
        proxy_pass http://odoo;
    }

    gzip on;
    gzip_types text/css text/plain application/json application/javascript image/svg+xml;
}

Esta configuración sigue la de la documentación de despliegue de Odoo. Activa el sitio, desactiva el de por defecto y recarga Nginx:

sudo ln -s /etc/nginx/sites-available/odoo /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx

Si usas UFW, permite solo HTTP y HTTPS (y SSH):

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'

Paso 6: Activar HTTPS con Let's Encrypt

Instala Certbot y solicita el certificado. Certbot añade el bloque HTTPS al archivo de Nginx y la redirección desde HTTP:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d odoo.example.com

Comprueba la renovación automática:

sudo certbot renew --dry-run
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/odoo.example.com/fullchain.pem (success)

Paso 7: Crear la base de datos de la empresa

Abre https://odoo.example.com. Como aún no hay bases de datos, Odoo muestra el formulario de creación. Rellena:

  • Master Password: la contraseña maestra que pusiste en admin_passwd.
  • Database Name: por ejemplo empresa. Usa solo letras minúsculas, números y guiones bajos.
  • Email y Password: el usuario administrador de la empresa. Es el que usarás para entrar en Odoo, distinto de la contraseña maestra.
  • Language y Country: el idioma de la interfaz y el país, que determina el paquete de localización contable que se instala.
  • Demo data: déjalo desmarcado en producción.

Al pulsar Create database, Odoo crea la base de datos y te lleva a la pantalla de aplicaciones.

Paso 8: Cerrar el gestor de bases de datos

Con una sola base de datos por dominio, la documentación de Odoo recomienda ocultar la lista de bases de datos y desactivar el gestor. Así nadie puede usar /web/database/manager para listar, copiar o borrar bases de datos ni para intentar adivinar la contraseña maestra. Edita la configuración:

sudo nano /etc/odoo/odoo.conf

Añade al final del bloque [options]:

dbfilter = ^empresa$
list_db = False

Reinicia Odoo:

sudo systemctl restart odoo

Comprueba que el gestor está desactivado:

curl -s https://odoo.example.com/web/database/manager | grep -o 'The database manager has been disabled by the administrator'
The database manager has been disabled by the administrator

Si más adelante necesitas crear otra base de datos o restaurar una copia desde el navegador, vuelve a poner list_db = True temporalmente.

Paso 9: Instalar aplicaciones y módulos

Entra con el usuario administrador y abre el menú Aplicaciones. Cada aplicación (Ventas, Facturación, Inventario, CRM, etc.) se instala con el botón Activar y añade sus menús de inmediato. Con workers activos, las instalaciones largas pueden tardar; no recargues la página mientras tanto.

Para módulos de terceros o propios, crea un directorio fuera del paquete, para que las actualizaciones de apt no lo toquen:

sudo mkdir -p /opt/odoo/custom-addons
sudo chown -R odoo:odoo /opt/odoo/custom-addons

Copia allí cada módulo (un directorio con su __manifest__.py) y añade la ruta a /etc/odoo/odoo.conf, junto con la de los módulos estándar:

addons_path = /usr/lib/python3/dist-packages/odoo/addons,/opt/odoo/custom-addons

Reinicia Odoo, activa el modo desarrollador en Ajustes y pulsa Actualizar lista de aplicaciones en el menú Aplicaciones para que aparezcan los módulos nuevos.

Paso 10: Programar copias de seguridad

Una copia completa de Odoo necesita dos partes: la base de datos de PostgreSQL y el filestore, donde Odoo guarda los adjuntos. Con el paquete Debian, el filestore está en /var/lib/odoo/.local/share/Odoo/filestore/<base_de_datos>. Crea un script:

sudo nano /usr/local/sbin/odoo-backup
#!/usr/bin/env bash
set -euo pipefail

db="empresa"
backup_dir="/var/backups/odoo"
filestore="/var/lib/odoo/.local/share/Odoo/filestore/${db}"
stamp="$(date +%Y%m%d-%H%M%S)"

mkdir -p "$backup_dir"

# Volcado en formato personalizado de PostgreSQL (se restaura con pg_restore)
runuser -u postgres -- pg_dump -Fc "$db" > "$backup_dir/${db}-db-${stamp}.dump"

# Adjuntos
tar -czf "$backup_dir/${db}-filestore-${stamp}.tar.gz" -C "$(dirname "$filestore")" "$db"

# Conservar 14 días
find "$backup_dir" -type f -name "${db}-*" -mtime +14 -delete

Hazlo ejecutable y pruébalo:

sudo chmod 750 /usr/local/sbin/odoo-backup
sudo /usr/local/sbin/odoo-backup
sudo ls -lh /var/backups/odoo
-rw-r--r-- 1 root root 9.8M Sep 25 11:02 empresa-db-20260925-110210.dump
-rw-r--r-- 1 root root  34M Sep 25 11:02 empresa-filestore-20260925-110210.tar.gz

Prográmalo cada noche a las 2:30:

echo '30 2 * * * root /usr/local/sbin/odoo-backup' | sudo tee /etc/cron.d/odoo-backup

Copia /var/backups/odoo a otro servidor o a un almacenamiento externo con regularidad. Para restaurar, crea una base de datos vacía propiedad de odoo, carga el volcado con pg_restore y descomprime el filestore en su ruta con propietario odoo.

Paso 11: Mantener Odoo actualizado

El repositorio de Odoo publica compilaciones diarias de la versión 19.0 con correcciones. Se actualizan con el resto del sistema:

sudo apt update
sudo apt upgrade

Tras actualizar el paquete, reinicia Odoo y actualiza los módulos instalados en la base de datos para aplicar posibles cambios de esquema. Haz antes una copia de seguridad:

sudo /usr/local/sbin/odoo-backup
sudo systemctl stop odoo
sudo -u odoo odoo -c /etc/odoo/odoo.conf -d empresa -u all --stop-after-init
sudo systemctl start odoo

El salto entre versiones mayores (por ejemplo, de 19.0 a 20.0) no es una simple actualización de paquete: requiere migrar la base de datos y conviene planificarlo aparte.

Solución de problemas

Error 502 Bad Gateway. Odoo no está escuchando en 127.0.0.1:8069. Revisa sudo systemctl status odoo y /var/log/odoo/odoo-server.log. Un error de sintaxis en odoo.conf impide el arranque.

Los PDF salen sin cabecera ni pie de página, o no se generan. Comprueba que wkhtmltopdf --version muestra with patched qt. Si Odoo sigue sin generar informes, revisa que el parámetro del sistema report.url (Ajustes, modo desarrollador, Técnico > Parámetros del sistema) apunte a http://127.0.0.1:8069.

Mensaje de conexión perdida o el chat no se actualiza. El websocket no llega al proceso gevent. Verifica que el bloque location /websocket está en el server HTTPS que creó Certbot y que el puerto 8072 aparece en ss -tlnp.

Workers reiniciados por memoria. Si en el registro ves que se matan workers por superar el límite de memoria, reduce workers o añade RAM al servidor.

Conclusión

Tienes Odoo 19 Community funcionando en Ubuntu 24.04 con PostgreSQL, en modo multiproceso detrás de Nginx con HTTPS, con el gestor de bases de datos cerrado y copias de seguridad diarias. Como siguientes pasos, configura un servidor de correo saliente en Ajustes > Técnico > Servidores de correo saliente, invita a los usuarios de tu equipo y activa solo las aplicaciones que vayáis a usar para mantener el sistema ligero.