Ir al contenido

Odoo en Google Cloud: cómo alojarlo bien

Odoo en Google Cloud: cómo alojarlo bien
noviembre 3, 2026 · 23 min leído

La respuesta corta

Para alojar Odoo en Google Cloud, hazlo correr en una VM de Compute Engine con un tipo de máquina x86 estándar, como e2-standard-2. Pon Postgres en la misma VM o en Cloud SQL con una IP privada. Abre solo los puertos 80 y 443, y entra a través de IAP en lugar de SSH público. Envía las copias de la base de datos y de los archivos a un bucket de Cloud Storage en el que la VM puede escribir, pero no leer ni borrar. No uses tipos de máquina shared-core en producción, y prueba una restauración antes de salir en vivo.

Muchas empresas ya tienen un proyecto de Google Cloud, así que Odoo también va allí. Google Cloud tiene regiones en todos los continentes. También tiene muchas formas de dejar Odoo un poco mal configurado. Esta guía te da los comandos exactos para cada paso en Google Cloud.

Para la instalación en sí (Odoo, Postgres, el archivo de configuración y el proxy), sigue nuestra guía sobre Odoo en un VPS. Esta página cubre lo que cambia en Google Cloud.

Puedes ejecutar cada comando gcloud de abajo desde tu propio equipo con la Google Cloud CLI, o desde Cloud Shell en la consola. Cambia los nombres en mayúsculas por los tuyos. La mayoría de los comandos necesitan una zona o una región. Fíjalas una vez para no tener que escribirlas:

gcloud config set project PROJECT_ID
gcloud config set compute/region europe-west1
gcloud config set compute/zone europe-west1-b

Qué tipo de máquina elegir

El mínimo para empezar: 2 vCPU, 4 GB de memoria y 50 GB de disco. Con eso corren Odoo y Postgres en una sola VM para un equipo pequeño. La memoria importa más que la CPU: cada worker necesita su parte, y Postgres quiere la suya. Para más usuarios, importaciones grandes o Cloud SQL, nuestra guía sobre cuántos workers de Odoo necesitas muestra cómo calcularlo.

Por qué no un tipo shared-core

Los tipos e2-micro, e2-small y e2-medium son "shared-core". Muestran 2 vCPU al sistema, pero solo tienes una parte de ellas todo el tiempo:

  • e2-micro: un cuarto de vCPU
  • e2-small: media vCPU
  • e2-medium: una vCPU

Pueden usar las 2 vCPU completas en ráfagas cortas, de 30 segundos a 2 minutos, y solo de vez en cuando. Odoo trabaja todo el día mientras la gente lo usa. Así que cuando acaba la ráfaga, Odoo va más lento.

Los tipos shared-core están bien para una copia de prueba que usa poca gente.

Tipos estándar para producción

Elige un tipo estándar con vCPU completas. Algunos ejemplos, todos con 2 vCPU y 8 GB de memoria:

  • e2-standard-2. Una buena opción por defecto para un equipo pequeño.
  • n2-standard-2. Un chip más nuevo y más rápido.
  • n4-standard-2. El más nuevo de los tres. Solo acepta Hyperdisk (mira la nota sobre el disco más abajo).

Si Postgres corre en la misma VM y la base de datos es grande, un tipo "highmem" da más memoria por vCPU. Por ejemplo, n4-highmem-2 tiene 2 vCPU y 16 GB.

Solo x86, si quizá nos dejes el trabajo más adelante

Google Cloud también vende tipos de máquina Arm: Tau T2A, y tipos Axion como C4A y N4A. Nuestro software bring your own server solo funciona en servidores x86. Si quizá nos dejes el trabajo de Odoo más adelante, quédate en tipos x86 como los de arriba.

Imagen

Usa Ubuntu 22.04 LTS (familia de imagen ubuntu-2204-lts, proyecto ubuntu-os-cloud) o Debian 12 (familia de imagen debian-12, proyecto debian-cloud). wkhtmltopdf, que Odoo usa para imprimir los PDF, tiene paquetes oficiales para los dos: Ubuntu 22.04 (jammy) y Debian 12 (bookworm). Imprime una factura antes de salir en vivo.

Disco

Guarda todo en el disco de arranque, o en otro persistent disk. No uses Local SSD para los datos: es un disco temporal.

El tipo de disco depende del tipo de máquina:

  • E2 y N2: usa pd-balanced.
  • N4: usa hyperdisk-balanced. N4 no acepta Persistent Disk en absoluto.

Deja sitio para el filestore y tres días de copias locales. Puedes hacer un disco más grande más tarde, pero nunca más pequeño.

Región

Elige la región con cuidado. Tus datos viven en la región que elijas. Pon la VM y Cloud SQL en la misma región. El bucket de copias va en una segunda región a propósito, como se muestra abajo.

Dónde va Postgres

Tienes dos buenas opciones:

  • En la misma VM. Simple, y está bien para muchos equipos. Sigue la guía del VPS tal como está.
  • En Cloud SQL for PostgreSQL. Google se encarga del servidor de base de datos, los parches y la recuperación a un momento dado. Los pasos están abajo.

Dale a Cloud SQL una dirección privada

Cloud SQL debe tener solo una IP privada, dentro de tu red VPC. Para eso, la red necesita "private services access". Esta guía usa la red default. Ejecuta esto una vez:

gcloud services enable servicenetworking.googleapis.com sqladmin.googleapis.com compute.googleapis.com

gcloud compute addresses create google-managed-services-default \
  --global \
  --purpose=VPC_PEERING \
  --prefix-length=16 \
  --network=default

gcloud services vpc-peerings connect \
  --service=servicenetworking.googleapis.com \
  --ranges=google-managed-services-default \
  --network=default

El primer comando activa las APIs. El segundo reserva un bloque de direcciones privadas para los servicios de Google. El tercero conecta ese bloque a tu red. Para esto necesitas el rol Compute Network Admin.

Crea la base de datos

gcloud sql instances create odoo-db \
  --database-version=POSTGRES_16 \
  --edition=enterprise \
  --cpu=2 --memory=8GB \
  --region=europe-west1 \
  --network=default \
  --no-assign-ip \
  --storage-type=SSD \
  --storage-size=50 \
  --backup-start-time=01:00 \
  --retained-backups-count=14 \
  --enable-point-in-time-recovery \
  --retained-transaction-log-days=7 \
  --ssl-mode=ENCRYPTED_ONLY \
  --deletion-protection

Qué hacen estas opciones:

  • --edition=enterprise elige la edición Enterprise. Desde Postgres 16, Cloud SQL elige Enterprise Plus si no le dices otra cosa. Enterprise Plus usa otros tipos de máquina y no acepta --cpu ni --memory.
  • --network=default --no-assign-ip le da a la base de datos una IP privada y ninguna pública.
  • --backup-start-time=01:00 hace una copia cada noche a la 01:00 UTC.
  • --retained-backups-count=14 guarda 14 de ellas. El valor por defecto en Enterprise es 7.
  • --enable-point-in-time-recovery te deja restaurar a cualquier segundo de los últimos 7 días. 7 días es lo máximo que guarda Enterprise.
  • --ssl-mode=ENCRYPTED_ONLY rechaza las conexiones sin SSL. El valor por defecto permite las dos.
  • --deletion-protection impide que alguien borre la base de datos por error.
  • Añade --availability-type=regional si quieres una copia en espera en una segunda zona.

El almacenamiento crece solo cuando se llena. Nunca se reduce.

Busca la dirección privada de la base de datos:

gcloud sql instances describe odoo-db --format="value(ipAddresses[0].ipAddress)"

Abajo la llamamos CLOUD_SQL_IP.

Crea el usuario de base de datos odoo

Odoo necesita su propio usuario que pueda crear bases de datos. No uses el usuario admin postgres en el día a día.

Cloud SQL crea el usuario postgres sin contraseña. Ponle una:

gcloud sql users set-password postgres --instance=odoo-db --prompt-for-password

En la VM de Odoo, conéctate con psql y crea el usuario:

psql "host=CLOUD_SQL_IP user=postgres dbname=postgres sslmode=require"
CREATE ROLE odoo WITH LOGIN CREATEDB PASSWORD 'a-long-random-password';

El usuario postgres no es un superusuario completo de Postgres, pero puede crear roles como este. Creamos odoo con SQL, no con gcloud sql users create. Un usuario creado con gcloud entra en el grupo cloudsqlsuperuser y también puede crear roles, cosa que Odoo no necesita.

Comprueba que odoo puede entrar en la base de datos postgres. Odoo se conecta allí para el chat y para las tareas programadas:

psql "host=CLOUD_SQL_IP user=odoo dbname=postgres sslmode=require" -c "SELECT current_user;"

Deja que Odoo cree su base de datos

Crea yourdb conectado como odoo, para que odoo sea su dueño. Usa una vez el gestor de bases de datos de Odoo, antes de poner list_db = False, o ejecuta esto como usuario odoo:

odoo -c /etc/odoo/odoo.conf -d yourdb -i base --stop-after-init

Revisa el dueño:

psql "host=CLOUD_SQL_IP user=odoo dbname=postgres sslmode=require" -c "\l yourdb"

Si prefieres crearla como postgres, Postgres 16 necesita primero que postgres sea miembro de odoo:

GRANT odoo TO postgres;
CREATE DATABASE yourdb OWNER odoo ENCODING 'UTF8' LC_COLLATE 'C' TEMPLATE template0;

Apunta Odoo a Cloud SQL

En odoo.conf:

db_host = CLOUD_SQL_IP
db_port = 5432
db_user = odoo
db_password = a-long-random-password
db_sslmode = require
db_maxconn = 16

db_sslmode = require hace que Odoo use siempre SSL, que ahora la base de datos exige.

Vigila el límite de conexiones

Cada proceso de Odoo tiene su propio pool de hasta db_maxconn conexiones. El valor por defecto es 64. Cuenta un pool por worker, uno por worker de cron (max_cron_threads, 2 por defecto) y uno para el proceso del chat. Con 4 workers, son 7 pools. Cloud SQL fija su propio límite según el tamaño de la máquina. Revísalo:

psql "host=CLOUD_SQL_IP user=odoo dbname=postgres sslmode=require" -c "SHOW max_connections;"

Los pools por db_maxconn deben quedar por debajo de ese número. Con 7 pools y db_maxconn = 16, Odoo puede abrir como máximo 112.

Usa la misma versión del cliente de Postgres

pg_dump no hace copia de un servidor con una versión mayor más nueva que la suya. Si Cloud SQL corre Postgres 16, la VM de Odoo necesita el cliente de la versión 16. Instálalo desde el repositorio apt de PostgreSQL:

sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
sudo apt install -y postgresql-client-16

Comprueba que las dos coinciden:

pg_dump --version
psql "host=CLOUD_SQL_IP user=odoo dbname=postgres sslmode=require" -c "SHOW server_version;"

Las copias de Cloud SQL no cubren el filestore

Cloud SQL hace copia de la base de datos y puede restaurarla a cualquier segundo dentro del periodo de recuperación. No hace copia del filestore. Los adjuntos y las imágenes viven en el disco de la VM, en /var/lib/odoo/filestore. Sigues necesitando la copia en Cloud Storage de abajo, para que la base de datos y los archivos se guarden juntos.

Red, service account y la VM

Una service account para la VM

La VM necesita una identidad en Google Cloud. Le permite enviar logs y métricas de disco y, más tarde, escribir las copias. Cada VM nueva recibe la "Compute Engine default service account" si no eliges otra. Esa cuenta puede tener el rol Editor en todo tu proyecto. Crea una aparte con solo lo que Odoo necesita:

gcloud iam service-accounts create odoo-server --display-name="Odoo server"
SA=odoo-server@PROJECT_ID.iam.gserviceaccount.com

gcloud projects add-iam-policy-binding PROJECT_ID \
  --member="serviceAccount:$SA" --role=roles/logging.logWriter
gcloud projects add-iam-policy-binding PROJECT_ID \
  --member="serviceAccount:$SA" --role=roles/monitoring.metricWriter

Una VM tiene dos capas de acceso: los "scopes" de la VM y los roles de IAM de la cuenta. Las dos deben permitir una llamada. Google aconseja poner el scope completo cloud-platform y controlar el acceso solo con roles de IAM. Eso es lo que hace la VM de abajo.

Reglas de firewall

La VM recibe una etiqueta de red, odoo. Las reglas de firewall apuntan a esa etiqueta, no a una dirección IP.

Abre los puertos web a todo el mundo:

gcloud compute firewall-rules create odoo-allow-web \
  --network=default --direction=INGRESS --action=allow \
  --rules=tcp:80,tcp:443 --source-ranges=0.0.0.0/0 \
  --target-tags=odoo

Permite SSH solo desde IAP, el túnel de acceso de Google. IAP siempre se conecta desde 35.235.240.0/20:

gcloud compute firewall-rules create odoo-allow-iap-ssh \
  --network=default --direction=INGRESS --action=allow \
  --rules=tcp:22 --source-ranges=35.235.240.0/20 \
  --target-tags=odoo

La red default trae reglas que abren el puerto 22 y el puerto 3389 a todo internet, para cada VM de la red. Lístalas:

gcloud compute firewall-rules list --filter="network=default"

Si nada más en el proyecto las necesita, bórralas:

gcloud compute firewall-rules delete default-allow-ssh default-allow-rdp

Los puertos propios de Odoo (8069 y 8072) siguen cerrados. Ninguna regla los abre, así que Google Cloud los bloquea. Solo nginx, en la VM, habla con ellos.

Una dirección fija

Reserva una IP externa estática, para que la dirección no cambie cuando la VM se detiene y arranca:

gcloud compute addresses create odoo-ip --region=europe-west1
gcloud compute addresses describe odoo-ip --region=europe-west1 --format="value(address)"

Apunta el registro DNS de tu dominio a esa dirección antes de pedir un certificado a Let's Encrypt.

Crea la VM

gcloud compute instances create odoo-prod \
  --zone=europe-west1-b \
  --machine-type=e2-standard-2 \
  --image-family=ubuntu-2204-lts --image-project=ubuntu-os-cloud \
  --boot-disk-size=50GB --boot-disk-type=pd-balanced \
  --service-account="$SA" --scopes=cloud-platform \
  --tags=odoo \
  --address=odoo-ip \
  --metadata=enable-oslogin=TRUE

Para un tipo N4, usa --boot-disk-type=hyperdisk-balanced. Para Debian, usa --image-family=debian-12 --image-project=debian-cloud.

enable-oslogin=TRUE activa OS Login. Entras con tu cuenta de Google y sus roles de IAM, no con claves SSH guardadas en la VM.

Entra a través de IAP, no con SSH público

Date los roles para entrar. Los dueños del proyecto ya los tienen:

gcloud projects add-iam-policy-binding PROJECT_ID \
  --member=user:[email protected] --role=roles/iap.tunnelResourceAccessor
gcloud projects add-iam-policy-binding PROJECT_ID \
  --member=user:[email protected] --role=roles/compute.osAdminLogin
gcloud iam service-accounts add-iam-policy-binding "$SA" \
  --member=user:[email protected] --role=roles/iam.serviceAccountUser
  • iap.tunnelResourceAccessor te deja usar el túnel de IAP.
  • compute.osAdminLogin te deja entrar con sudo. Usa roles/compute.osLogin para la gente que no necesita sudo.
  • iam.serviceAccountUser hace falta porque la VM corre como la cuenta odoo-server.

Luego conéctate:

gcloud compute ssh odoo-prod --zone=europe-west1-b --tunnel-through-iap

La VM tiene una IP pública, así que debes añadir --tunnel-through-iap. Sin eso, gcloud prueba la dirección pública, y allí el puerto 22 está cerrado.

Revisa lo que está abierto

Desde tu propio equipo, no desde Cloud Shell, comprueba que los puertos privados están cerrados. Los dos comandos deben dar timeout:

nc -vz -w 5 STATIC_IP 22
curl -m 5 http://STATIC_IP:8069

Y que el sitio responde:

curl -I https://odoo.example.com/web/login

Copias de seguridad en Cloud Storage

Crea el bucket

Pon el bucket en una región distinta de la VM. Si toda la región tiene un problema, tus copias siguen a salvo. Déjalo en una región donde tus datos pueden estar.

gcloud storage buckets create gs://your-odoo-backups \
  --location=europe-west4 \
  --uniform-bucket-level-access \
  --public-access-prevention \
  --soft-delete-duration=30d

Los nombres de bucket se comparten entre todos los clientes de Google Cloud, así que añade algo único al tuyo. No puedes mover un bucket después de crearlo.

  • --location=europe-west4 es una segunda región. También puedes usar una dual-region, que guarda dos copias en dos regiones. Por ejemplo, EUR4 es Finlandia más Países Bajos, y NAM4 es Iowa más Carolina del Sur.
  • --uniform-bucket-level-access significa que solo IAM decide quién entra. No hay permisos por archivo.
  • --public-access-prevention bloquea cualquier enlace público al bucket.
  • --soft-delete-duration=30d guarda los archivos borrados 30 días antes de que se vayan para siempre. Los buckets nuevos los guardan 7 días. Puedes recuperar un archivo con soft delete desde la consola o con gcloud.

Google aconseja soft delete en lugar del versionado de objetos, así que esta guía usa soft delete. De todos modos, tus archivos de copia nunca se sobrescriben, como muestran los pasos siguientes.

Revisa la configuración:

gcloud storage buckets describe gs://your-odoo-backups

Borra las copias viejas de forma programada

Guarda esto como lifecycle.json:

{
  "rule": [
    {
      "action": { "type": "Delete" },
      "condition": { "age": 30 }
    }
  ]
}
gcloud storage buckets update gs://your-odoo-backups --lifecycle-file=lifecycle.json
gcloud storage buckets describe gs://your-odoo-backups --format="default(lifecycle_config)"

Las copias de más de 30 días se borran. Con soft delete activo, "borrada" primero significa "oculta". La copia oculta se queda 30 días más y luego se va para siempre. Una regla nueva puede tardar hasta 24 horas en empezar a funcionar.

Deja que la VM escriba, y solo escriba

Dale a la service account de la VM un solo rol, solo en este bucket:

gcloud storage buckets add-iam-policy-binding gs://your-odoo-backups \
  --member="serviceAccount:$SA" --role=roles/storage.objectCreator

gcloud storage buckets get-iam-policy gs://your-odoo-backups

roles/storage.objectCreator puede crear archivos. No puede listarlos, leerlos, sobrescribirlos ni borrarlos. Si alguien entra en el servidor, no puede borrar tus copias.

Un detalle. Para archivos de más de 150 MiB, gcloud divide la subida en partes y las une al final. Unir y limpiar las partes necesita permisos de lectura y de borrado, que este rol no tiene. Así que desactívalo para el usuario odoo, en la VM:

sudo -u odoo -H gcloud config set storage/parallel_composite_upload_enabled False
sudo -u odoo -H gcloud config get storage/parallel_composite_upload_enabled

Los archivos grandes se siguen subiendo, solo que en un único flujo.

Si tus normas piden más, una retention policy puede bloquear los borrados durante un tiempo fijo, incluso para un admin. Por ejemplo, gcloud storage buckets update gs://your-odoo-backups --retention-period=30d. Si luego la bloqueas con --lock-retention-period, nunca podrás quitarla ni acortarla. Pruébalo antes en un bucket de sobra.

La gcloud CLI en la VM

Puede que tu imagen ya traiga la Google Cloud CLI. Compruébalo en la VM:

gcloud --version

Si no está, instálala desde el repositorio apt de Google:

curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
sudo apt-get update && sudo apt-get install -y google-cloud-cli

En la VM, gcloud usa la service account sola. Nunca guardas una clave en el servidor.

El script de copia

Primero crea la carpeta local:

sudo mkdir -p /backups
sudo chown odoo:odoo /backups

Guarda esto como /usr/local/bin/odoo-backup.sh y ejecuta sudo chmod 755 sobre él:

#!/bin/bash
# /usr/local/bin/odoo-backup.sh, run as the odoo user
set -euo pipefail
DB=yourdb
DAY=$(date +%F)
DIR=/backups/$DAY
mkdir -p "$DIR"
pg_dump -Fc "$DB" > "$DIR/$DB.dump"
tar -czf "$DIR/$DB-filestore.tar.gz" -C /var/lib/odoo/filestore "$DB"
gcloud storage cp "$DIR"/* "gs://your-odoo-backups/$DAY/"
find /backups -mindepth 1 -maxdepth 1 -type d -mtime +3 -exec rm -rf {} +

La VM no puede sobrescribir archivos en el bucket. Así que si el script se ejecuta dos veces el mismo día, la segunda subida falla. Es a propósito: una copia que ya está en el bucket no se puede sustituir.

Con Cloud SQL, pg_dump debe conectarse por la red. Cambia la línea de pg_dump por:

pg_dump -h CLOUD_SQL_IP -U odoo -Fc "$DB" > "$DIR/$DB.dump"

Luego dale al usuario odoo su contraseña en un archivo .pgpass, en su carpeta personal:

sudo -u odoo -H bash -c 'echo "CLOUD_SQL_IP:5432:*:odoo:a-long-random-password" > ~/.pgpass && chmod 600 ~/.pgpass'

El * hace que la misma línea sirva para todas las bases de datos, también la de la prueba de restauración.

Ejecútalo cada noche

Crea /etc/systemd/system/odoo-backup.service:

[Unit]
Description=Odoo backup to Cloud Storage
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
User=odoo
ExecStart=/usr/local/bin/odoo-backup.sh

Y /etc/systemd/system/odoo-backup.timer:

[Unit]
Description=Run the Odoo backup every night

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true

[Install]
WantedBy=timers.target

Actívalo, luego ejecútalo una vez a mano y revisa el resultado:

sudo systemctl daemon-reload
sudo systemctl enable --now odoo-backup.timer
sudo systemctl start odoo-backup.service
journalctl -u odoo-backup.service -n 20

Desde tu propio equipo, comprueba que los archivos llegaron:

gcloud storage ls --recursive gs://your-odoo-backups/

Prueba una restauración

La VM de producción no puede leer el bucket. Es a propósito. Así que la prueba de restauración se hace en una segunda VM con su propia service account de solo lectura. Crea la cuenta y dale acceso de lectura al bucket:

gcloud iam service-accounts create odoo-restore --display-name="Odoo restore test"
RSA=odoo-restore@PROJECT_ID.iam.gserviceaccount.com

gcloud storage buckets add-iam-policy-binding gs://your-odoo-backups \
  --member="serviceAccount:$RSA" --role=roles/storage.objectViewer

roles/storage.objectViewer puede listar y leer archivos. No puede escribirlos ni borrarlos.

Crea la VM de prueba con esa cuenta, la misma etiqueta y sin IP estática:

gcloud compute instances create odoo-restore-test \
  --zone=europe-west1-b \
  --machine-type=e2-standard-2 \
  --image-family=ubuntu-2204-lts --image-project=ubuntu-os-cloud \
  --boot-disk-size=50GB --boot-disk-type=pd-balanced \
  --service-account="$RSA" --scopes=cloud-platform \
  --tags=odoo \
  --metadata=enable-oslogin=TRUE

Para entrar, date también roles/iam.serviceAccountUser sobre $RSA, como hiciste con $SA. Instala Odoo en ella con la guía del VPS.

En la VM de prueba, como usuario odoo, descarga la copia de una noche y restáurala:

mkdir -p /tmp/restore && cd /tmp/restore
gcloud storage cp "gs://your-odoo-backups/2026-10-25/*" .
createdb -O odoo yourdb_restored
pg_restore -d yourdb_restored --no-owner --role=odoo yourdb.dump
mkdir -p /var/lib/odoo/filestore/yourdb_restored
tar -xzf yourdb-filestore.tar.gz -C /var/lib/odoo/filestore/yourdb_restored --strip-components=1

Si la copia de prueba usa Cloud SQL, añade -h CLOUD_SQL_IP -U odoo a createdb y a pg_restore.

Antes de arrancar Odoo en la copia, neutralízala. Una copia de producción sigue teniendo tus servidores de correo y tus tareas programadas, así que puede enviar correos a clientes reales. Como usuario odoo, ejecuta:

odoo neutralize -c /etc/odoo/odoo.conf -d yourdb_restored

Usa odoo-bin en lugar de odoo si ejecutas Odoo desde el código fuente. Esto apaga en la copia los servidores de correo saliente, las acciones programadas y los proveedores de pago. Nuestra guía sobre copiar producción a staging explica lo que cubre y lo que se le escapa.

Luego entra en yourdb_restored y abre algunos adjuntos. Nuestra guía sobre cómo saber si una copia de Odoo se restaurará cubre la prueba completa.

Recibe una alerta antes de que el disco se llene

Los logs, el filestore y las copias locales crecen. Google Cloud no ve lo lleno que está tu disco si la VM no le envía ese dato. El Ops Agent lo hace.

Instálalo en la VM:

curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh
sudo bash add-google-cloud-ops-agent-repo.sh --also-install
sudo systemctl status google-cloud-ops-agent"*"

El estado debe mostrar en marcha las partes de logs y de métricas. El agente usa los roles logWriter y metricWriter que le diste a la service account.

La alerta de disco

Crea un canal de correo para las alertas, y apunta su nombre:

gcloud beta monitoring channels create --display-name="Odoo alerts" \
  --type=email [email protected]
gcloud beta monitoring channels list --format="value(name,displayName)"

La métrica es agent.googleapis.com/disk/percent_used. Tiene una línea por partición de disco, con el nombre en su etiqueta device. Así que primero busca el nombre de la partición raíz. En la consola, ve a Monitoring > Metrics explorer, elige VM Instance > Disk > Disk utilization, filtra por state = used y agrupa por device. En la VM, findmnt -n -o SOURCE / muestra la misma partición, por ejemplo /dev/sda1. Usa el nombre tal como lo muestra Metrics explorer.

Busca el ID de la VM:

gcloud compute instances describe odoo-prod --zone=europe-west1-b --format="value(id)"

Guarda esto como disk-alert.json, con tu nombre de device y el ID de tu VM:

{
  "displayName": "Odoo disk above 80%",
  "combiner": "OR",
  "conditions": [
    {
      "displayName": "Root disk used above 80%",
      "conditionThreshold": {
        "filter": "metric.type=\"agent.googleapis.com/disk/percent_used\" AND resource.type=\"gce_instance\" AND resource.labels.instance_id=\"INSTANCE_ID\" AND metric.labels.state=\"used\" AND metric.labels.device=\"DEVICE\"",
        "aggregations": [
          { "alignmentPeriod": "300s", "perSeriesAligner": "ALIGN_MEAN" }
        ],
        "comparison": "COMPARISON_GT",
        "thresholdValue": 80,
        "duration": "0s",
        "trigger": { "count": 1 }
      }
    }
  ]
}
gcloud monitoring policies create --policy-from-file=disk-alert.json \
  --notification-channels=CHANNEL_NAME

Filtrar por un solo device deja fuera los pequeños discos de solo lectura que Ubuntu añade para los paquetes snap. Esos siempre se ven llenos al 100%.

Un uptime check

Comprueba también que el sitio en sí responde. En la consola, ve a Monitoring > Uptime checks > Create Uptime Check y configura:

  • Protocol: HTTPS
  • Resource Type: URL
  • Hostname: tu dominio de Odoo
  • Path: /web/login

Deja la alerta activada y elige tu canal Odoo alerts. Recibes un correo cuando al menos dos regiones de control no llegan a la página durante un minuto.

Correo saliente

Compute Engine bloquea las conexiones salientes al puerto 25 de servidores externos. El correo de Odoo enviado así nunca sale. Los puertos 587 y 465 están abiertos. Así que envía a través de un servicio SMTP en uno de ellos. Tu proveedor de correo actual sirve. Si usas Google Workspace, su SMTP relay funciona solo en el 587 o el 465.

En Odoo, activa el modo desarrollador. Ve a Settings > Technical > Outgoing Mail Servers. Pon el servidor SMTP de tu proveedor, el puerto 587 con cifrado TLS (STARTTLS), o el puerto 465 con SSL/TLS, y el usuario y la contraseña SMTP.

Trampas de Odoo en cualquier servidor, Google Cloud incluido

Websocket. Desde Odoo 16, el chat y las actualizaciones en vivo usan el puerto 8072. nginx debe enviar /websocket allí, con las cabeceras de upgrade.

Proxy mode. Odoo solo confía en las cabeceras reenviadas cuando proxy_mode = True y la petición trae X-Forwarded-Host. Sin las dos cosas, tus enlaces salen con http://.

Gestor de bases de datos. Pon list_db = False y un admin_passwd fuerte.

Workers. Pon workers por encima de 0, ajustado a la memoria. Así Odoo arranca el worker del chat en gevent_port.

En odoo.conf:

proxy_mode = True
list_db = False
admin_passwd = a-long-random-string
workers = 4
gevent_port = 8072

En nginx, junto a tu bloque location /:

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

location /websocket {
  proxy_pass http://127.0.0.1:8072;
  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;
}

El bloque map va en la sección http, fuera de server.

Detrás de un balanceador de carga de Google Cloud

No necesitas un balanceador de carga para una sola VM. Si usas de todos modos un Application Load Balancer externo:

  • Gestiona los websockets sin configuración extra. Deja nginx detrás de él, para que /websocket siga yendo al 8072.
  • Mantiene la cabecera Host original y envía X-Forwarded-Proto y X-Forwarded-For, pero no X-Forwarded-Host. Sin ella, Odoo ignora las otras. Así que nginx debe añadirla.
  • Termina el HTTPS, así que nginx ve HTTP plano. Pasa el protocolo del balanceador, no el de nginx.
  • El timeout de su backend service es de 30 segundos por defecto. Si se cortan los informes largos o las conexiones del chat, súbelo.

En los dos bloques location de nginx, usa:

proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;

Luego cambia odoo-allow-web para que el puerto 80 quede abierto solo al balanceador, no a todo internet. El balanceador y sus health checks vienen de 35.191.0.0/16 y 130.211.0.0/22:

gcloud compute firewall-rules update odoo-allow-web \
  --rules=tcp:80 --source-ranges=35.191.0.0/16,130.211.0.0/22

Antes de salir en vivo

  • La VM es de un tipo x86 estándar (no shared-core), con un disco pd-balanced o hyperdisk-balanced
  • La VM corre con su propia service account, no con la de por defecto
  • Odoo corre con workers por encima de 0, ajustado a la memoria del servidor
  • /websocket va al puerto 8072, y el chat funciona
  • proxy_mode = True, y los enlaces de los correos empiezan por https://
  • list_db = False y un admin_passwd fuerte
  • Solo están abiertos a internet los puertos 80 y 443, default-allow-ssh ya no existe, y entras a través de IAP
  • Con Cloud SQL: solo IP privada, ENCRYPTED_ONLY, db_sslmode = require, y pg_dump coincide con la versión del servidor
  • El certificado SSL se renueva solo
  • Los PDF se imprimen (wkhtmltopdf funciona)
  • Los correos de prueba llegan, enviados por el puerto 587 o 465
  • Los logs rotan, el Ops Agent funciona, y la alerta de disco y el uptime check avisan a tu correo
  • El timer de la copia se ejecutó, y los archivos están en el bucket, en otra región
  • Una copia se ha restaurado en otra VM, y los adjuntos se abren

Quédate con Google Cloud, déjanos el trabajo de Odoo

Puedes mantener Odoo en tu proyecto de Google Cloud y aun así no gestionarlo tú mismo. Con bring your own server, la VM sigue en tu proyecto y en la región que elijas. Nosotros hacemos funcionar Odoo en ella: despliegues desde Git, staging, copias de seguridad, actualizaciones y ayuda de expertos en Odoo. Tú mantienes la VM en marcha y con el tamaño suficiente. Nuestro software se conecta desde tu VM hacia fuera, así que no nos abres ningún puerto.

Skysize está hecho por ex ingenieros de Odoo y tiene la certificación ISO 27001.

Habla con un experto en hosting de Odoo

Preguntas frecuentes

¿Puede Odoo correr en Google Cloud? Sí. Usa una VM de Compute Engine, Postgres en la VM o en Cloud SQL, y copias de seguridad en Cloud Storage.

¿Puedo usar Cloud SQL para Odoo? Sí. Dale una IP privada, activa SSL, y crea para Odoo un usuario de base de datos que pueda crear bases. Cloud SQL no hace copia del filestore, así que cópialo también.

¿Qué tipo de máquina es el mejor para Odoo? Uno con suficiente memoria para tus workers y Postgres, y vCPU completas, como e2-standard-2 o n4-standard-2. Evita los tipos shared-core como e2-medium en producción.

¿Puede Odoo correr en tipos de máquina Arm como C4A o T2A? Esta guía no los cubre. Nuestro software bring your own server solo funciona en x86, así que elige un tipo x86 si quizá nos dejes el trabajo más adelante.

¿Qué rol de IAM necesita la VM de Odoo para las copias? Solo roles/storage.objectCreator en tu bucket de copias. Las restauraciones usan otra service account, en otra VM, con roles/storage.objectViewer.

¿Tengo que abrir el puerto 22? No a internet. Permite el puerto 22 solo desde el rango de IAP, 35.235.240.0/20, y conéctate con gcloud compute ssh --tunnel-through-iap.

¿Por qué Odoo no envía correo desde Compute Engine? Google Cloud bloquea el puerto 25 de salida hacia servidores externos. Envía a través de tu proveedor de correo en el puerto 587 o 465.

Odoo en Google Cloud: cómo alojarlo bien
Escribe sobre la infraestructura de Odoo en Skysize, un proveedor de hosting de Odoo con sede en Bélgica, creado por exingenieros de Odoo y certificado ISO 27001, que sirve a empresas y agencias en todo el mundo.