What Is a Staging Environment?
A staging environment is a near-identical copy of your production Odoo instance that runs on a separate server. Same Odoo version, same modules, same data structure — but isolated from your live business.
Think of it as a dress rehearsal. You test everything in staging first — module upgrades, custom code, Odoo version bumps, configuration changes — and only push to production once you're confident nothing breaks.
Why You Need Staging
Running Odoo updates directly on production is gambling with your business. Here's what staging prevents:
Module conflicts
Third-party modules can break when Odoo updates. Staging catches incompatibilities before users notice.
Data migration failures
Odoo version upgrades run data migrations that can fail on your specific data patterns.
Performance regressions
A new module or custom query might slow down key workflows. Test under realistic load.
Custom code bugs
Python overrides and JS patches need testing against real data, not empty databases.
Setting Up a Staging Server
Your staging server should mirror production as closely as possible. Same operating system, same PostgreSQL version, same Odoo version. The only differences should be intentional (less RAM is fine, different domain).
Minimum staging specs
| Component | Production | Staging (minimum) |
|---|---|---|
| RAM | 8-16 GB | 4 GB |
| CPU | 4+ vCPUs | 2 vCPUs |
| Disk | 100+ GB SSD | 50 GB SSD |
| PostgreSQL | Same version | Same version |
| Odoo | Same version | Same version |
| OS | Ubuntu 22.04 | Ubuntu 22.04 |
Staging can run on a smaller server than production — you're testing functionality, not load capacity. A $10-20/month VPS is enough for most teams.
Cloning Production to Staging
Two things to copy: the PostgreSQL database and the filestore (attachments, documents).
Step 1: Database dump
# On production serverpg_dump -Fc -Z 5 -f /tmp/odoo_prod.dump odoo_production# Copy to stagingscp /tmp/odoo_prod.dump staging:/tmp/Step 2: Restore to staging
# On staging serversudo systemctl stop odoo# Drop and recreatesudo -u postgres dropdb odoo_stagingsudo -u postgres createdb -O odoo odoo_staging# Restorepg_restore -d odoo_staging /tmp/odoo_prod.dumpsudo systemctl start odooStep 3: Sync filestore
# Sync attachments from production to stagingrsync -avz --delete \ production:/opt/odoo/.local/share/Odoo/filestore/odoo_production/ \ /opt/odoo/.local/share/Odoo/filestore/odoo_staging/Data Sanitization
After cloning, sanitize staging data immediately. You don't want staging sending real emails to customers or processing real payments.
-- Run on staging database after restore-- Disable all outgoing mail serversUPDATE ir_mail_server SET active = false;-- Reset all user passwords to a random value-- Generate one with: openssl rand -base64 16UPDATE res_users SET password = (SELECT gen_random_uuid()::text) WHERE id > 2;-- Anonymize partner emails (keep admin)UPDATE res_partner SET email = 'staging+' || id || '@example.com' WHERE email IS NOT NULL AND id > 2;-- Clear payment provider credentialsUPDATE payment_provider SET state = 'disabled';-- Disable scheduled mail actionsUPDATE ir_cron SET active = false WHERE name ILIKE '%mail%' OR name ILIKE '%email%';-- Clear webhook URLsDELETE FROM ir_config_parameter WHERE key ILIKE '%webhook%';Important: Run this SQL immediately after restoring the database, before starting Odoo. If Odoo starts before sanitization, it may fire off queued emails or cron jobs using real customer data.
Configuration Differences
Your staging odoo.conf should differ from production in a few key ways:
[options]; Use a different databasedb_name = odoo_staging; Different port to avoid conflictshttp_port = 8070longpolling_port = 8072; Fewer workers (staging needs less)workers = 2max_cron_threads = 1; Enable dev mode for easier testingdev_mode = reload,qweb; Separate log filelogfile = /var/log/odoo/odoo-staging.log; Staging URLdb_filter = odoo_stagingSet up a staging subdomain (e.g., staging.yourcompany.com) with its own SSL certificate. This keeps URLs clean and makes it obvious which environment you're in.
Testing Workflow
A solid staging workflow follows these steps:
Refresh staging data
Clone production database and filestore. Run sanitization scripts.
Deploy changes to staging
Pull latest code, install/upgrade modules. Watch the logs for errors.
Functional testing
Walk through key business processes — create a sale order, confirm it, generate an invoice. Test what your users actually do.
Regression testing
Verify that existing features still work. Check reports, email templates, automated actions.
Promote to production
Once staging passes, apply the same changes to production during a maintenance window.
OEC.sh: One-Click Staging
All of the above — server provisioning, database cloning, data sanitization, SSL setup, email disabling — takes hours the first time and 30+ minutes on every refresh. OEC.sh does it in one click.
One-click clone
Clone production to staging with a single button. Database, filestore, and configuration are all copied automatically.
Auto-sanitization
Sensitive data is anonymized during cloning. No manual SQL scripts needed.
Staging subdomain
Each staging instance gets its own URL with automatic SSL. Share with your team for testing.
Promote to production
When testing is done, promote staging changes to production. OEC.sh handles the deployment.
FAQ
What is an Odoo staging environment?
A staging environment is a copy of your production Odoo instance used for testing. It mirrors your production setup — same Odoo version, modules, and data structure — but runs on a separate server with its own database. You test module updates, custom code, and configuration changes in staging before applying them to production.
How often should I refresh my staging environment?
Refresh staging from production at least monthly, or before any major update. Stale staging data leads to false confidence — a module upgrade that works on 3-month-old data might fail on current production data. Automate the refresh with a cron script that runs weekly during off-hours.
Can I use the same server for staging and production?
You can, but it creates risk. Staging load can affect production performance, and a misconfigured staging database could accidentally overwrite production data. Use separate servers or at minimum separate Docker containers with isolated networks. The cost of a small staging VPS ($5-20/month) is negligible compared to a production outage.
How do I handle email in staging?
Never let staging send real emails to customers. Options: (1) Disable all outgoing mail servers in Odoo settings, (2) Route all staging email to a catch-all service like Mailtrap or MailHog, (3) Run a SQL script after cloning that clears ir.mail_server records and sets email_from to a test address. OEC.sh staging environments disable outgoing mail by default.
What about staging for Odoo Enterprise?
Odoo Enterprise licenses are tied to your production instance. For staging, you can use the same Enterprise code on a test database — Odoo SA allows this for development and testing purposes. The staging instance should not serve real users or process real transactions. Check your Odoo Partnership Agreement for specific terms.
How does OEC.sh handle staging?
OEC.sh provides one-click staging environments. Clone your production instance, and OEC.sh creates a separate server with its own database, automatically sanitizes sensitive data, disables outgoing email, and gives it a staging subdomain. When testing is done, promote changes to production with a single click. Available on Growth plan and above.