Case study

How an Odoo partner upgrades more than 20 client projects without losing a weekend

A look inside how one Odoo partner runs upgrades across more than 20 client projects without a single lost weekend.

CICDoo Team 4 min read

In short

An Odoo partner managing more than 20 client projects routes every upgrade through a staging environment and a Git push webhook before it ever reaches production. Over the last six months they completed more than 1000 upgrades and merges with an 85% success rate, backed by automatic backups and a median production uptime of 99.9%.

On this page
  1. The problem every growing Odoo partner hits
  2. The setup: staging first, webhook always
  3. What six months of that looks like
  4. What you can copy, even at a smaller scale
  5. Running your own fleet this way

The problem every growing Odoo partner hits

At some point, running client Odoo instances stops being a technical job and becomes a logistics job. One of our customers, an Odoo partner running more than 20 client projects with more than 20 production instances, lives entirely on that side of the line. Each client has its own repository, its own branch, often its own combination of Community and Enterprise, and its own Odoo version, spanning everything from 14.0 to 20.0 across the fleet.

At that scale, the question is never "can we upgrade this client". It is "how do we upgrade twenty of them without one bad merge taking down a production database at 6pm on a Friday".

The setup: staging first, webhook always

The partner's workflow leans on a small set of features used consistently across every project, rather than anything exotic:

  • Staging and development environments for every client, so a change is never tested for the first time in production.
  • Upgrade on merge through the Git push webhook: merging a branch in the Console pushes to the target branch, and the instance running that branch redeploys automatically. There is no manual "now copy this to production" step to forget.
  • Extra module repositories, since most client instances pull in more than one codebase (the core Odoo apps plus one or more private module repos).
  • AI coding agent tasks, which can draft the mechanical parts of an upgrade, a dependency bump, a deprecated API call, a changed field name, while a person still reads and approves every plan before anything is written.
  • Custom domains and auto restart on every client instance, so each one behaves like its own production system rather than a shared sandbox.

The branch-to-instance mapping is what makes this workable at volume: a development branch, a staging branch and a production branch per client, each one permanently wired to its own instance. Promoting a change is a merge, not a deployment script someone has to remember to run.

What six months of that looks like

Over the last 180 days, the partner ran more than 1000 upgrades and merges across the fleet, with an 85% success rate. That number is worth sitting with for a second: it means roughly one in six needed a second attempt. At that volume, what matters is that a failed upgrade stops on its own instance and reports why, instead of quietly reaching a client's live database.

The backup and restore numbers tell the rest of the story. In the same six months they took between 51 and 200 backups and ran between 51 and 200 restores. Restores at that volume are what you see when backups are a working tool rather than something kept only for emergencies, for example restoring production onto staging to rehearse a risky change before it ships. Restarts in the same window landed between 201 and 1000, which is what you would expect from more than 20 projects deploying and redeploying constantly across development, staging and production.

The outcome across all of that: a median production uptime of 99.9% over the trailing 30 days, measured instance by instance in the Monitoring tab.

What you can copy, even at a smaller scale

None of this depends on the size of the fleet. The pattern holds at two client projects as well as at twenty:

  1. Never let a branch skip staging. If production only ever receives merges from a staging branch that itself only receives merges from development, a bad change has at least one chance to get caught before it reaches a client's live database.
  2. Let the webhook do the deployment. A merge that automatically redeploys the target instance removes the step most likely to be forgotten under pressure, the manual "now deploy it" after the merge.
  3. Take the backup before the merge, not after the incident. A backup taken as a matter of routine, right before a risky change, is the difference between a ten-minute restore and a bad afternoon.
  4. Use an agent for the repetitive part of an upgrade, a human for the decision. Agent tasks can draft the mechanical fixes an upgrade usually needs. They always stop and wait for a plan to be approved first, and production runs are deliberately harder to trigger than staging ones, so the agent speeds up the typing without ever skipping the review.
  5. Watch uptime per instance, not per fleet. A single average can hide one struggling client behind nineteen healthy ones. Looking at each instance's own chart, rather than a fleet-wide number, is what actually catches a problem early.

Running your own fleet this way

This setup is not unusual among Odoo partners on CICDoo, it is closer to the default once a fleet passes a handful of clients. If you are still promoting changes by hand, talk to an engineer about moving to a staging-first, webhook-driven setup, or start a project and build it from the first client onward.

FAQ

Questions, answered

Does upgrading on merge mean every push goes straight to production?

No. Upgrade on merge only redeploys the instance that owns the branch you merged into. A typical flow still goes development, then staging, then production, each one its own merge and its own review point, as described in Merging branches between stages.

Can an AI agent touch a production instance directly?

It can be pointed at one, but production is deliberately awkward on purpose: the task has to be confirmed at creation and again at the plan stage, and unattended auto-execute is refused outright on production. Nothing runs on a live client database without a person reading the plan first. See What agent tasks are.

How do you recover from a bad merge on a client's production instance?

Restore the backup taken just before the merge, fix the conflict on a development or staging branch, and merge again once staging confirms the fix. The Backups and restore tab keeps every instance's backups for the whole project, so a production backup can even be restored onto staging to reproduce the problem safely.

Run your Odoo like this

CICDoo deploys, backs up, monitors and upgrades Odoo from your Git branches, on servers you own. Talk to an engineer about your setup.

No per-seat fees. Your servers stay yours.