OCA Days

Liège 2026

Making Odoo mightier, together

Deploying Odoo on Kubernetes

a production-ready Helm chart and the lessons behind it

Alexandre Nuttinck

DevOps Team Lead

iMio
OCA Days

Liège 2026

Who am I?

Alexandre Nuttinck Alexandre Nuttinck · DevOps Team Lead · iMio · Les Isnes, Wallonia, Belgium

I discovered the OCA three years ago, when I joined iMio. I was here last year, with a talk about multitenancy in Odoo.

github.com/alexnuttinck · [email protected]

Odoo on Kubernetes · OCA Days Liège 2026

iMio in numbers

Indicator Value Context
Belgian local authorities 450+ municipalities, CPAS, police and rescue zones
Applications we build and run 13 open source, mutualised across all members
Odoo tenants 151 iA·Vision 80 · iA·AES 69 · Mon Territoire · internal Odoo
Odoo on Kubernetes · OCA Days Liège 2026

1. Choosing how to run Odoo

Odoo.sh is a great fit for many teams. This part is about the teams it isn't a fit for.

Odoo on Kubernetes · OCA Days Liège 2026

Why run Odoo yourself?

  • Compliance: public sector data, our datacenter, our rules
  • Multitenancy: 80 tenants behind one instance, not 80 subscriptions
  • Cost: mutualisation is in our DNA, and in our budget
  • Integration: Odoo is one workload among many on the same cluster
  • Control: our images, our modules
Odoo on Kubernetes · OCA Days Liège 2026

The options on the table

Option Good at Trade-off
Plain manifests Total freedom Copy-paste across environments
Plain manifests + Kustomize Overlays per environment No templating, no releases
Bitnami chart Batteries included Their image, their assumptions
Your own operator Full lifecycle automation A controller to write and run
Your own chart Fits exactly You maintain it
Odoo on Kubernetes · OCA Days Liège 2026
QR code for github.com/IMIO/helm-odoo

Our call: write our own chart

  • github.com/IMIO/helm-odoo: Apache-2.0
  • Charts published on imio.github.io/helm-charts
  • We already speak Helm: nearly every iMio workload ships this way
  • No operator needed: Odoo has no lifecycle worth a CRD
  • Signed releases since 3.0.1
  • Opinionated on purpose: built for our needs, open to yours
Odoo on Kubernetes · OCA Days Liège 2026

2. Inside the chart

Four decisions that shaped the chart.

Odoo on Kubernetes · OCA Days Liège 2026

Helm, in one slide

Helm is the package manager for Kubernetes. A chart packages a whole deployment so it can be published, versioned and reused, by one team or by everyone.

A chart is templates plus values. Templating is the mechanism; the contract is the point: a developer changes values.yaml and never opens a manifest.

replicaCount: 3
image:
  tag: "19.0"
odoo:
  workers: 12
  limit_memory_hard: 2684354560
cron:
  enabled: true
Odoo on Kubernetes · OCA Days Liège 2026

PostgreSQL: bundled or external

Bundled · postgresql.enabled: true External · postgresql.enabled: false
Chart CloudPirates, official image, PG 17 CloudNativePG operator
Storage Ephemeral Replicated, backed up, PITR
Use for Dev, CI, a kind cluster Production.
Odoo on Kubernetes · OCA Days Liège 2026

NAIVE

Just add replicas.

one upload, two filestores

A user uploads to pod A and gets a 404 from pod B

FIXED

Move the state out of the pod.

the state lives once, outside

Stateless pods writing to S3 and PostgreSQL

Odoo on Kubernetes · OCA Days Liège 2026

Scaling: replicas, workers, cron

replicaCount: 3          # 3 pods × 12 workers ≈ 36 concurrent requests
odoo:
  workers: 12
  max_cron_threads: 0    # forced to 0 when cron.enabled
cron:
  enabled: true          # crons get their own deployment
  strategy: Recreate     # never two cron pods at once

Web traffic scales horizontally. Cron does not, so it moves out.

Odoo on Kubernetes · OCA Days Liège 2026

Upgrades: the Helm hooks do the work

What actually happens, over time

⚠️ odoo.update.enabled: true + odoo.update.modules: all is a one-shot intent. Leave it on and you rerun a full migration, downtime included, on every redeploy.

Odoo on Kubernetes · OCA Days Liège 2026

3. Running it in production

A chart is not a deployment strategy.

Odoo on Kubernetes · OCA Days Liège 2026

GitOps: git decides, ArgoCD applies

  • Git is the source of truth: ArgoCD applies what was merged, and nothing else
  • Three things, versioned separately: the chart version, the values, the extra manifests
  • A developer opens a merge request on values.yaml and never touches the cluster
  • selfHeal: whatever someone changed by hand at 2am gets quietly put back
Odoo on Kubernetes · OCA Days Liège 2026

One chart, sixty-nine instances

One repository, a shared defaults file, one version file, 69 instances

Odoo on Kubernetes · OCA Days Liège 2026

Four different workloads, one chart

Workload Shape Storage Status
iA·Vision Multi-tenant, 80 DBs, 3 replicas CloudNativePG + S3 + sessions_db Production
Mon Territoire Single-tenant CloudNativePG + S3 + sessions_db Staging, prod landing
iA·AES 69 instances, one per customer CloudNativePG + S3 + sessions_db VMs today, K8s next
Internal Odoo Odoo Enterprise, 1 replica CloudNativePG + RWO ZFS volume Production
Odoo on Kubernetes · OCA Days Liège 2026

▶ Live demo

Everything you just saw, on a laptop

A kind cluster, the chart from the public repo, the bundled PostgreSQL. First an install
from nothing. Then a version bump: replicas to zero, maintenance page, odoo -u all, and
back up with a different logo on the login screen.

Same chart as production. Only values.yaml and the image tag differ.

~5 min · kind + helm · chart 3.1.0

What's next

Three things on the roadmap, in the order we'll actually get to them.

🚚

Migrate iA·AES

69 instances off VMs and Puppet onto the chart, one folder at a time.

🔁

Auto mode

Let the chart decide whether an upgrade needs a migration, and a maintenance page, at all. module_auto_update (OCA) is the candidate.

🧩

Multi-tenant upgrades

Today it's a Kubernetes Job outside the chart: 80 databases, 10 in parallel, ~15 minutes.

Odoo on Kubernetes · OCA Days Liège 2026
QR code for github.com/IMIO/helm-odoo

Kind reminder

  • The chart is open: adopt it, fork it, or steal the parts that work
Odoo on Kubernetes · OCA Days Liège 2026

Thank you!

Questions ?

github.com/IMIO/helm-odoo · [email protected] · @alexnuttinck

Going further: kubernetes.io/docs · Multitenancy talk youtu.be/ggDsdvJm38s

Thank you to OCA’s Platinum and Gold Sponsors

Platinum

Gold

What broke along the way

  • update.enabled left on: every sync scaled Odoo to zero and re-ran the migration
  • One filestore, two replicas: attachments appeared and vanished depending on the pod
  • Bundled DB + hooks: the migration Job started before PostgreSQL existed
  • Wrong UID: Odoo 15 and Odoo 18 don't ship the same default UID, and nothing could write
Odoo on Kubernetes · OCA Days Liège 2026

Three things to take home

  • Kubernetes doesn't make Odoo stateless: the database and the filestore decide your architecture, not your YAML
  • Helm hooks turn a migration into a reproducible step: the same command runs on a laptop and in production
  • The chart is open: adopt it, fork it, or steal the parts that work
Odoo on Kubernetes · OCA Days Liège 2026