An exoskeleton for Odoo development
osh is a CLI that runs Odoo your way — it discovers your addons, maps
git branches to databases, and picks the right runtime (host, venv, or
Docker) so osh odoo just works.
- Branch-aware databases — each git branch gets its own
<project>-<branch>database; switching never reuses the wrong one - Zero boilerplate — addons paths and Odoo configuration are auto-discovered and generated
- Runtimes — run on the host, in a managed virtualenv, or in a Docker Compose stack
- Backups that travel —
osh backup restorefrom odoo.sh, a live server, an Odoo database manager, or a file - Transparent —
--dry-runprints the exact command it would run - Pluggable — pip-installed plugins add commands, runtimes, and backup source schemes
Note:
oshis not related to or affiliated with Odoo S.A. or itsodoo.shservice.
Contents: Quick start · Guide · Commands · Runtimes · Design principles · Plugins · Contributing · License
New to osh? The getting-started guide walks through a full session — install, init, real data, daily work.
Requirements: Python ≥ 3.10 and git (plus Docker for the docker
runtime and psql/createdb for database commands).
Install osh with pipx (it keeps the tool in an
isolated environment; osh is not on PyPI, so install from the repo).
@latest installs the most recent released version — omit it to install
the unreleased tip of master:
pipx install git+https://github.com/dreispt/osh@latestOn an existing project directory initialize the osh run environment and then start Odoo:
# Create a project directory
cd my-odoo-project
# Initialise it for Odoo 19.0 — on the first run you'll be asked which
# runtime to use (the answer is remembered in ~/.config/osh/config.toml)
osh init 19.0
# Run Odoo
osh odooNo need to remember the target database or config file: the database name
is detected from the current git branch and the addons paths are
auto-discovered. osh init is safe to re-run at any time — see
docs/INIT.md for the full story, including osh init extra-addons and the runtime subcommands.
To restore a real database into the project: osh backup get <source>
downloads a backup from a file or an Odoo database manager URL, and
osh backup restore <source> applies it to the current branch's
database — see docs/GETTING-STARTED.md for a
full walkthrough.
Run osh <command> --help for full usage details, and
docs/GETTING-STARTED.md for a walkthrough of a
full session.
| Command | What it does |
|---|---|
osh init [version] [dir] |
Initialise a project; osh init <runtime> selects the runtime; bare run reports status |
osh odoo [args] |
Run Odoo with the project's env auto-configured (osh odoo shell, osh odoo -u mymod, ...) |
osh exec |
Enter the project's runtime environment or run a command in it |
osh stop |
Stop whatever the active runtime left running |
osh test |
Run Odoo tests for project modules |
osh db |
List, show, set, copy, drop, exec, or unset project databases |
osh backup |
Get, list, or restore database backups, and register named remote sources |
osh config |
View or change osh settings for this project |
osh --help always reflects what's actually installed — core commands,
bundled plugins, and pip-installed plugins listed together.
A runtime is where osh runs Odoo and its tools; osh init <runtime>
picks one and osh odoo, osh exec and osh db run through it.
- host — run whatever Odoo the machine already has (the default); covered in docs/INIT.md
- venv — managed virtualenv plus Odoo sources; docs/VENV.md
- docker — Odoo and PostgreSQL in a Docker Compose stack; docs/DOCKER.md
- doodba — adopt a Doodba project's Compose stack (experimental); docs/DOODBA.md
- Say what you do –
osh odooruns Odoo, just likeodoo-binwould, with the project's env pre-configured.osh execgives you a shell. No command's name and behavior disagree. - Mirror the tool underneath – anything you'd pass to
odoo-bin(shell,-u mymodule,scaffold, ...) works the same way afterosh odoo. You're not learning a second CLI vocabulary. - One noun, one home – osh subcommands represent a domain or resource
to operate on. For example, everything that manages project databases
(list, copy, mapping to branches, ...) lives under
osh db. - Unintrusive – a thin layer on top of Odoo for common dev workflows; it won't modify your project or force a particular deployment or organization mode.
- Transparent – see what's actually running at any time.
--dry-runprints the assembled command instead of executing it, on every command that runs one. Defaults you didn't ask for (like Odoo dev mode) always show up in that output. - Pluggable – grow the toolbelt with plugins;
pipx inject osh <dist>and new commands show up alongside the built-ins.
osh is extensible: plugins can add commands, runtimes, backup
source schemes and extend core commands in place. The bundled plugins provide osh backup
(get, restore, list, remote) and osh test, plus the venv and
docker runtimes (the host runtime is built in).
Community plugins live in osh-contrib.
Plugins are Python packages installed into the osh environment —
with pipx that is pipx inject:
pipx inject osh git+https://github.com/dreispt/osh-contrib(If osh was installed with plain pip, use pip install instead.)
Highlights include:
osh apps uninstall mod_a,mod_b— uninstall modules and their installed dependents.osh odoo --open— print the browser URL once Odoo is ready (--openalso opens it).
See PLUGINS.md for how to write and publish your own plugins.
Run osh --help or osh <command> --help for detailed usage information.
The command list is generated automatically from the core commands plus bundled
and installed plugins, so osh --help always reflects what is actually
available in your setup.
Contributions are welcome. See DEVELOP.md for the development setup, test suite, and conventions, and PLUGINS.md for the plugin API.
Copyright © 2026 Daniel Reis
Distributed under the GNU LGPL-3.0-only license.
