Skip to main content
DevOpsFebruary 20, 202610 min read

Odoo Staging Environment Guide

Test module updates, custom code, and configuration changes on a copy of production before touching the live system. Here's how to set up staging properly.

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

ComponentProductionStaging (minimum)
RAM8-16 GB4 GB
CPU4+ vCPUs2 vCPUs
Disk100+ GB SSD50 GB SSD
PostgreSQLSame versionSame version
OdooSame versionSame version
OSUbuntu 22.04Ubuntu 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 server
pg_dump -Fc -Z 5 -f /tmp/odoo_prod.dump odoo_production
# Copy to staging
scp /tmp/odoo_prod.dump staging:/tmp/

Step 2: Restore to staging

# On staging server
sudo systemctl stop odoo
# Drop and recreate
sudo -u postgres dropdb odoo_staging
sudo -u postgres createdb -O odoo odoo_staging
# Restore
pg_restore -d odoo_staging /tmp/odoo_prod.dump
sudo systemctl start odoo

Step 3: Sync filestore

# Sync attachments from production to staging
rsync -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 servers
UPDATE ir_mail_server SET active = false;
-- Reset all user passwords to a random value
-- Generate one with: openssl rand -base64 16
UPDATE 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 credentials
UPDATE payment_provider SET state = 'disabled';
-- Disable scheduled mail actions
UPDATE ir_cron SET active = false
WHERE name ILIKE '%mail%' OR name ILIKE '%email%';
-- Clear webhook URLs
DELETE 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 database
db_name = odoo_staging
; Different port to avoid conflicts
http_port = 8070
longpolling_port = 8072
; Fewer workers (staging needs less)
workers = 2
max_cron_threads = 1
; Enable dev mode for easier testing
dev_mode = reload,qweb
; Separate log file
logfile = /var/log/odoo/odoo-staging.log
; Staging URL
db_filter = odoo_staging

Set 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:

1

Refresh staging data

Clone production database and filestore. Run sanitization scripts.

2

Deploy changes to staging

Pull latest code, install/upgrade modules. Watch the logs for errors.

3

Functional testing

Walk through key business processes — create a sale order, confirm it, generate an invoice. Test what your users actually do.

4

Regression testing

Verify that existing features still work. Check reports, email templates, automated actions.

5

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.

Related Guides