Odoo Development

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.

iWesabe Editorial TeamJuly 2, 20208 min read

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

Odoo.sh branch types and their purpose
Branch typePurposeDatabaseAuto-rebuild on push?Email sending
ProductionLive customer-facing environment. Only one production branch per project.Live data — real customer recordsYes (on merge/push). Odoo.sh updates the running instance in-place.Enabled — uses real mail servers
StagingPre-production testing. Database is a recent copy of production — same data, no live traffic.Copy of production (auto-neutralised)Yes — rebuilds on each pushDisabled by default — emails are intercepted and not sent to real recipients
DevelopmentFeature development and testing with demo data or a fresh database. Multiple development branches allowed.Demo data or manual install — no production dataYes — rebuilds on each pushDisabled 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:

text
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

bash
# 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 tab

Adding 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.

bash
# 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 main

Python 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.

text
# 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

bash
# 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, restarts

Monitoring Build Logs and Diagnosing Failures

Common Odoo.sh build failure patterns and fixes
Error pattern in logsCauseFix
ModuleNotFoundError: No module named 'xyz'A Python package required by a module is missing from requirements.txtAdd 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 pathsThe 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 foundSubmodule was added but .gitmodules was not committed, or the submodule was not initialisedRun 'git submodule update --init' locally, commit .gitmodules along with the submodule reference, and push again.
odoo.exceptions.ValidationError or MissingError during buildA data file (XML/CSV) in the module references a record that doesn't exist in the target databaseTest 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.sh deployment changes by Odoo version
Odoo versionKey changes affecting Odoo.sh module deployment
Odoo 15 & 16No 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 17Odoo.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 18No breaking changes to Odoo.sh deployment workflow. Submodule handling and requirements.txt unchanged. Odoo 18 branches in OCA are named 18.0.
Odoo 19No 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.

WhatsApp

Frequently Asked Questions

How do I deploy a custom module on Odoo.sh?
Add your module directory (containing `__manifest__.py`) to the GitHub repository connected to your Odoo.sh project. Commit and push — Odoo.sh automatically detects the module, rebuilds the branch, and adds it to the Apps list. To install it, go to Apps in Odoo, search for your module name, and click Install. The module is not auto-installed on push; it must be manually installed the first time.
How do I add an OCA module to an Odoo.sh project?
Use git submodules. Run `git submodule add -b .0 https://github.com/OCA/.git OCA/` from your repository root, then commit both the `.gitmodules` file and the new submodule directory reference and push. Odoo.sh automatically initialises submodules during each build — you do not need to do anything on the server. Always use the branch matching your Odoo version (e.g. `-b 17.0` for Odoo 17).
What is the difference between staging and development branches in Odoo.sh?
A staging branch automatically receives a copy of the production database — same data, neutralised (email disabled, scheduled actions paused). Use staging to test module upgrades against real data before going live. A development branch uses demo data or a fresh database — no production data. Use development branches for feature development, initial module testing, and experimentation. You can have multiple development branches but only one staging and one production branch per Odoo.sh project.
Does Odoo.sh automatically install requirements.txt dependencies?
Yes. Place a `requirements.txt` file in the repository root. Odoo.sh runs `pip install -r requirements.txt` during each build before starting the Odoo server. It also scans all git submodules for `requirements.txt` files and installs those too. Pin your package versions (e.g. `zeep==4.2.1`) to avoid broken builds when upstream packages release breaking changes.
How do I promote a module change from staging to production on Odoo.sh?
Merge the staging branch into the production branch via GitHub (pull request or direct merge) and push. Odoo.sh detects the push to the production branch, triggers a build, and applies the module changes in-place — running `odoo -u ` automatically for any modules that have changed. The server is restarted as part of the update. Monitor the Build and Server logs in the Odoo.sh dashboard for any errors during the production update.
Can I use Odoo.sh for Odoo Community Edition (CE) modules?
Odoo.sh is designed for Odoo Enterprise — it requires an active Odoo Enterprise subscription. Community Edition modules (modules that only depend on `base` and other CE modules) can be deployed on Odoo.sh because Odoo.sh runs Enterprise, which includes all CE modules. However, you cannot run a pure CE instance on Odoo.sh. For pure CE deployments, use a self-managed server (VPS or on-premise) instead.
iWesabe Editorial Team

iWesabe Editorial Team

Practitioner insights on Odoo ERP, ZATCA compliance, and Saudi enterprise digital operations — written by iWesabe's consulting, finance, and engineering teams.

About iWesabe

Related Articles