How to Deploy Community Modules on Odoo.sh (Odoo 16–19)
A complete developer reference for deploying custom and OCA community modules on Odoo.sh: GitHub repository setup, branch workflow, submodules, requirements.txt, build logs, and staging-to-production promotion. Verified for Odoo 18 & 19.
Odoo.sh is Odoo's official cloud hosting platform, built around a GitHub-native branch-based deployment model. Every push to a connected GitHub repository triggers an automatic build on the corresponding Odoo.sh branch — no manual server provisioning required. Deploying community or custom modules on Odoo.sh follows a predictable workflow: add the module code to your repository, let Odoo.sh build it on a development or staging branch, verify it, then promote to production by merging the branch. This guide covers every step in that workflow.
The Odoo.sh Three-Branch Model
| Branch type | Purpose | Database | Auto-rebuild on push? | Email sending |
|---|---|---|---|---|
| Production | Live customer-facing environment. Only one production branch per project. | Live data — real customer records | Yes (on merge/push). Odoo.sh updates the running instance in-place. | Enabled — uses real mail servers |
| Staging | Pre-production testing. Database is a recent copy of production — same data, no live traffic. | Copy of production (auto-neutralised) | Yes — rebuilds on each push | Disabled by default — emails are intercepted and not sent to real recipients |
| Development | Feature development and testing with demo data or a fresh database. Multiple development branches allowed. | Demo data or manual install — no production data | Yes — rebuilds on each push | Disabled by default |
Repository Structure for Odoo.sh
Odoo.sh scans the repository root for directories that look like Odoo modules (containing a `__manifest__.py` file) and automatically adds them to the module path. Custom modules can be placed directly in the repository root or in a subdirectory. The recommended structure for a project with both custom modules and OCA dependencies:
my-odoo-project/ ← GitHub repository root
├── my_custom_module/ ← custom module (detected automatically)
│ ├── __manifest__.py
│ ├── __init__.py
│ ├── models/
│ └── views/
├── my_other_module/ ← another custom module
│ └── __manifest__.py
├── OCA/ ← OCA community modules (as git submodules)
│ ├── account-invoicing/ ← OCA repository submodule
│ │ └── account_invoice_xyz/ ← specific OCA module
│ └── partner-contact/
├── requirements.txt ← Python package dependencies
└── .gitmodules ← git submodule registry (auto-managed)Connecting Your GitHub Repository to Odoo.sh
# Step-by-step: first-time setup for a new Odoo.sh project
# 1. Create a GitHub repository for your project
# (either a new repo or fork an existing one)
# 2. Clone locally and add your custom module
git clone https://github.com/your-org/your-odoo-project.git
cd your-odoo-project
# 3. Add your custom module directory
mkdir my_custom_module
# ... add __manifest__.py, __init__.py, models/, views/ etc.
# 4. Commit and push to the branch Odoo.sh is watching
git add .
git commit -m "feat: add my_custom_module"
git push origin main # or 'master' depending on your default branch
# 5. In the Odoo.sh dashboard:
# - Go to your project → Branches tab
# - Your 'main' branch now appears as a Development branch
# - Odoo.sh automatically starts a build
# - Watch the build log in the Logs tabAdding OCA Community Modules via Git Submodules
OCA (Odoo Community Association) modules are maintained as separate GitHub repositories. The correct way to include them in an Odoo.sh project is as git submodules — this pins the OCA module to a specific commit, keeps your repository size small, and lets Odoo.sh automatically initialise the submodule during each build.
# Adding an OCA module as a git submodule
# Example: add the OCA 'account-invoicing' repository
# (contains multiple modules — Odoo.sh will scan it and find them all)
git submodule add -b 17.0 https://github.com/OCA/account-invoicing.git OCA/account-invoicing
# This creates:
# - OCA/account-invoicing/ directory (the submodule contents)
# - .gitmodules file entry registering the submodule
# Commit both the submodule reference and .gitmodules
git add .gitmodules OCA/account-invoicing
git commit -m "feat: add OCA account-invoicing submodule (17.0)"
git push origin main
# Odoo.sh will automatically run 'git submodule update --init' during each build.
# You do NOT need to run any extra commands on the server.
# To update the submodule to the latest commit on its branch later:
git submodule update --remote OCA/account-invoicing
git add OCA/account-invoicing
git commit -m "chore: update OCA account-invoicing to latest 17.0"
git push origin mainPython Dependencies — requirements.txt
If your custom modules or OCA modules depend on Python packages not included in the Odoo base installation, add a `requirements.txt` file to the repository root. Odoo.sh automatically runs `pip install -r requirements.txt` during each build before starting the Odoo server.
# requirements.txt — place in the repository root
# Pin versions for reproducible builds
zeep==4.2.1 # SOAP client (e.g. for ZATCA integration)
cryptography==41.0.3 # for custom encryption utilities
pandas==2.1.0 # for data export/import modules
openpyxl==3.1.2 # Excel export
# OCA modules sometimes list their own requirements.txt files
# inside the module directory — Odoo.sh scans for and installs those too.
# Your repo root requirements.txt is additive.Branch Promotion Workflow — Dev → Staging → Production
# Safe deployment workflow for a new module
# 1. Develop on a feature branch (development branch in Odoo.sh)
git checkout -b feature/my-new-module
# ... develop, commit, push
git push origin feature/my-new-module
# Odoo.sh auto-builds on 'feature/my-new-module' as a development branch
# 2. Test on development branch
# - Open Odoo.sh dashboard → feature/my-new-module → Connect (SSH or browser)
# - Install the module: Apps → search for your module → Install
# - Verify functionality with demo/test data
# 3. Merge to staging branch for pre-production testing
# Option A: via GitHub pull request to 'staging' branch
# Option B: via Odoo.sh dashboard → Staging tab → Merge branch
git checkout staging
git merge feature/my-new-module
git push origin staging
# Odoo.sh rebuilds staging with a copy of the production database
# The new module is NOT auto-installed — you must install it manually
# on the staging database to test the upgrade path
# 4. Verify on staging
# - Module installs correctly on a production-data copy
# - No data migration errors
# - Emails are intercepted — safe to test workflows
# 5. Merge to production
git checkout main # your production branch
git merge staging
git push origin main
# Odoo.sh applies the update in-place: runs module upgrade, restartsMonitoring Build Logs and Diagnosing Failures
| Error pattern in logs | Cause | Fix |
|---|---|---|
| ModuleNotFoundError: No module named 'xyz' | A Python package required by a module is missing from requirements.txt | Add the missing package to requirements.txt in the repository root. Commit and push — the next build will pip install it. |
| Cannot find module 'my_module' in addons paths | The module directory is missing __manifest__.py (so Odoo.sh doesn't recognise it as a module) | Add __manifest__.py to the module directory root. Without it, the directory is not added to the addons path. |
| Submodule directory is empty / OCA module not found | Submodule was added but .gitmodules was not committed, or the submodule was not initialised | Run 'git submodule update --init' locally, commit .gitmodules along with the submodule reference, and push again. |
| odoo.exceptions.ValidationError or MissingError during build | A data file (XML/CSV) in the module references a record that doesn't exist in the target database | Test the module install on a fresh database first. On staging (with production data), the record may exist in dev but not in production. Use noupdate='1' carefully and test data migration. |
Version Notes
| Odoo version | Key changes affecting Odoo.sh module deployment |
|---|---|
| Odoo 15 & 16 | No breaking changes to Odoo.sh branch model or submodule handling. OCA module branches follow 15.0/16.0 naming convention. requirements.txt auto-install unchanged. |
| Odoo 17 | Odoo.sh dashboard UI redesigned — branch management moved to a new Branches tab. Functionality unchanged. OCA branches use 17.0 naming. The module's __manifest__.py 'version' field should match the Odoo major version (e.g. '17.0.1.0.0'). |
| Odoo 18 | No breaking changes to Odoo.sh deployment workflow. Submodule handling and requirements.txt unchanged. Odoo 18 branches in OCA are named 18.0. |
| Odoo 19 | No breaking changes to Odoo.sh. The platform automatically supports Odoo 19 builds. OCA 19.0 branches available for supported repositories. Deployment workflow identical. |
Need Help Setting Up Odoo.sh or Deploying Custom Modules?
Our certified Odoo team handles full Odoo.sh project setup, GitHub repository structure, OCA module integration, and safe production deployment pipelines — including Arabic RTL modules, ZATCA integrations, and multi-company configurations for Saudi businesses.
Frequently Asked Questions
How do I deploy a custom module on Odoo.sh?
How do I add an OCA module to an Odoo.sh project?
What is the difference between staging and development branches in Odoo.sh?
Does Odoo.sh automatically install requirements.txt dependencies?
How do I promote a module change from staging to production on Odoo.sh?
Can I use Odoo.sh for Odoo Community Edition (CE) modules?

iWesabe Editorial Team
Practitioner insights on Odoo ERP, ZATCA compliance, and Saudi enterprise digital operations — written by iWesabe's consulting, finance, and engineering teams.
Related Articles
Odoo Database Management — Complete Guide to the Database Manager (Odoo 16–19)
A complete reference for Odoo's built-in database manager: create, duplicate, backup, restore, and delete databases — plus security hardening for production environments. Verified for Odoo 18 & 19.
Access Security in Odoo — ir.model.access.csv and Record Rules (Odoo 16–19)
A complete developer reference for Odoo's two-layer security system: model-level CRUD permissions via ir.model.access.csv and record-level filtering via ir.rule. Verified for Odoo 18 & 19.
How to Create a Custom Snippet in Odoo Website
Step-by-step guide to building reusable drag-and-drop building blocks for the Odoo Website editor — from XML template to live snippet panel. Verified for Odoo 18 & 19.
Explore Related Solutions
Financial Management
Automate your Saudi Arabia accounting — ZATCA Phase 2 e-invoicing, VAT returns, Zakat provisioning, multi-currency bank reconciliation, and real-time financial reporting — all inside one connected Odoo platform. Fully localised for KSA and the GCC by iWesabe.
ExploreManufacturing Management ERP
Run lean, traceable production with Odoo Manufacturing — work orders, Bills of Materials, quality control, and real-time OEE dashboards built for KSA factory floors.
ExploreCRM & Customer Relationship Management
Turn every lead into a closed deal. Odoo CRM gives your sales team a structured Kanban pipeline, automated follow-up sequences, and a 360° customer view — all connected natively to Accounting, Inventory, and Email Marketing.
ExploreSupply Chain Management
From purchase order to final delivery — Odoo Supply Chain connects procurement, multi-warehouse inventory, demand forecasting, and vendor management into one real-time platform. Purpose-configured for Saudi Arabia and the GCC by iWesabe.
Explore