Odoo modules are Python and XML that run inside the ERP's process and against its database, which means a module can pass every test on a laptop and still fail on production because production has 40,000 partner records with a field the test database never had. The safe way to develop is against real-shaped data, and this post shows an Odoo developer doing that on MassiveGRID PaaS, which is built on Virtuozzo Application Platform, formerly Jelastic, using cloned environments as disposable staging.
The developer is the in-house Odoo specialist at a manufacturing company we will call Brightwater Components, which runs the Odoo Community Edition package with about 60 users. His backlog: a custom module that syncs bills of materials with the shop-floor system, two OCA modules for quality management, and a minor-version upgrade.
The problem with a permanent staging server
Brightwater used to have a staging server. It was refreshed from production twice a year, so by the time a module reached it the data was stale, the module list had drifted, and two developers were sharing one database and overwriting each other's test records. Staging is only useful if it is a faithful copy of production as of this morning, and a permanent server is never that.
The platform's Clone Environment operation is. It copies the entire Odoo environment, the Python application container with its addons directory and filestore and the PostgreSQL container with its data, into a new environment with its own URL, in a few minutes. Every clone is a fresh copy of production at the moment of cloning, and it can be deleted when the work is done.
A day's workflow with clones
- Clone production to odoo-dev-bom-sync. The clone is in the same region and the same environment group, and the developer lowers its cloudlet limits because one user does not need production's headroom.
- Neutralise the clone. Odoo has a built-in neutralisation step for this purpose; the developer's script disables outgoing mail servers, scheduled actions that call external systems, and payment acquirers on the clone, so a test run never emails a customer or posts to the shop-floor API.
- Deploy the module into the clone's custom addons directory. The developer keeps modules in a Git repository and uses the platform's Deployment Manager to pull the branch into the addons path, or simply SFTP for a quick iteration.
- Update the module with
odoo-bin -d brightwater -u bom_sync --stop-after-initfrom the Web SSH console, watch the log, and open the clone in a browser to test against this morning's real data. - Delete the clone or keep it until the change is approved. A small clone used for four hours costs a few cents.
Two developers working on two modules get two clones, and neither can break the other's test data. A reviewer gets a URL, not a screenshot.
OCA modules without fear
The two quality-management modules come from the Odoo Community Association. OCA modules are well maintained, but they carry dependencies on other OCA modules and sometimes on Python packages, and installing them on production first is how a company discovers a missing dependency at 09:00. On a clone the developer installs the Python requirements, adds the OCA repository to the addons path, installs the modules from the Apps menu and runs Odoo's own test suite for them against the clone. If the installation would take too long or fail, production never knew.
| Change | Tested on | Promotion to production |
|---|---|---|
| Custom bom_sync module, first version | Clone, real data, neutralised | Pull the tagged branch, run -u bom_sync during the evening window |
| OCA quality modules | Clone, dependency check, test suite | Install Python requirements, then install from Apps |
| Odoo minor-version update | Clone, redeploy container, run -u all | Same steps, after a fresh backup |
Promoting to production without a second server
Production is one environment, so promotion is applying the same steps to it. For module code the developer merges the branch and the Deployment Manager pulls it; for module updates he runs the same -u command in a short evening window, because Odoo module updates lock tables and a 60-user company can tolerate ten minutes at 19:00. Before every promotion the Database Backup/Restore add-on takes an on-demand PostgreSQL backup, and because the platform can also clone production right before the change, the rollback plan is a clone he has already made.
For the minor-version update, the sequence is: clone, redeploy the clone's Odoo container to the new version tag (a container redeploy keeps the data volumes), run -u all, test, then repeat on production. The platform's redeploy is the same operation on both, which removes the usual difference between how staging and production were upgraded.
Keeping clones from calling home
The one risk in cloning an ERP is that the clone inherits production's integrations. Neutralisation covers Odoo's own outbound behaviour. For anything at the network level, the developer puts development clones in a separate environment group with network isolation so they cannot reach the production PostgreSQL node or the shop-floor connector over the internal network, and the container firewall on the clone can additionally block the external API hosts. It is the kind of guard you set up once and never think about again.
What the workflow changed
Module regressions on production went to zero in the six months after the change, not because the developer got better but because every change met real data before it met users. The staging server was decommissioned. The clones cost less per month than the staging server's power, and each was exactly as current as production.
Frequently Asked Questions
Does cloning copy the Odoo filestore (attachments) as well as the database?
Yes. A clone copies every container in the environment with its persistent storage, so the filestore directory comes with it. If the filestore is large, cloning takes longer and the clone's disk is billed while it exists, so delete clones you no longer need.
Can I point a clone at a copy of a specific backup instead of current production?
Yes. Clone the environment for its topology, then restore the desired dump into the clone's PostgreSQL through the backup add-on or with pg_restore over the Web SSH console. This is useful for reproducing a bug reported last week.
How do I run Odoo in developer mode on the clone?
Start the clone's Odoo with --dev=all in the container's start command (or edit the configuration file through the dashboard's config editor) and restart the node. Never leave developer mode enabled on production; the clone is the right place for it.
Test every module on this morning's data
Run Odoo Community Edition on MassiveGRID PaaS and clone production in minutes whenever you need a staging copy. Pay per cloudlet-hour for the clone, delete it when the change ships. Free 14-day trial, no credit card.
Odoo Community on MassiveGRID PaaS