Skip to main content

odoo-dev

A CLI tool for managing Odoo development environments. Handles local Python setup, Docker containers, database operations, and more.

It is the successor to the older odoo-deploy shell scripts — if you have notes for odoo-deploy, the rough mapping is: odoo-dev docker start/stop/build replaces the old odoo-dev.sh start/stop/build, and odoo-dev run/test/shell give you a local (venv-based) workflow that odoo-deploy didn't.

Installation

# Install with uv (recommended) — installs the published package from PyPI
uv tool install odoo-dev

# Or with pip
pip install odoo-dev

Then make sure the install location is on your PATH (uv prints the path; usually ~/.local/bin):

uv tool update-shell   # or: export PATH="$HOME/.local/bin:$PATH"

Quick Start

# In your Odoo project directory
cd my-odoo-project

# Full setup: clone Odoo repos, create venv, install deps, configure VSCode
odoo-dev setup

# Or for community edition only
odoo-dev setup --community

setup reads ODOO_VERSION / PYTHON_VERSION from a .env in the project root (or prompts for them and offers to save). It then clones the Odoo repos, builds a .venv, installs system dependencies, and generates conf/odoo.conf. It will offer to set up Docker at the end — answer "no" if you only want the local venv workflow.

Database setup (read this before your first run/test)

The generated conf/odoo.conf connects as PostgreSQL user odoo over the local socket. A running PostgreSQL server is a prerequisite you provide yourself — on every platform. setup installs only the PostgreSQL client and build dependencies (macOS: libpq; Linux: postgresql-client + libpq-dev); it never installs, starts, or configures a server, and never creates the odoo role. So on a fresh machine, install a server, start it, and create the role once:

macOS (Homebrew):

brew install postgresql@18                  # install a server (pick your version)
brew services start postgresql@18           # start it
createuser -s odoo                          # create the role odoo.conf expects
# Homebrew's versioned postgres is keg-only; add its bin to PATH if psql/createuser aren't found:
#   export PATH="$(brew --prefix postgresql@18)/bin:$PATH"

Debian/Ubuntu:

sudo apt-get install postgresql     # install a server if you don't already have one
sudo systemctl start postgresql
sudo -u postgres createuser -s odoo

Using a different / remote / Docker PostgreSQL: set DB_HOST, DB_PORT, DB_USER, DB_PASSWORD in .env before running setup (it writes them into conf/odoo.conf), or edit conf/odoo.conf directly. With no DB_HOST, odoo-dev connects over the local socket as the odoo role.

Before launching, run/test/shell/update run a quick connection preflight: if the server is unreachable, the role is missing, or authentication fails, you get a specific one-line fix instead of a stack trace.

Commands

Local Development (default)

odoo-dev run                          # Start Odoo locally (default port 8069)
odoo-dev run -d mydb -p 8070          # Pick a database and HTTP port
odoo-dev run -d mydb -i base          # Initialize module(s) on start
odoo-dev run -d mydb --dev reload     # With hot reload
odoo-dev run --debug                  # With debugpy (VSCode attach on 5678)
odoo-dev shell mydb                   # Open an Odoo shell
odoo-dev update base -d mydb          # Update modules
odoo-dev test my_module               # Run a module's tests (coverage on by default)
odoo-dev test my_module --test-tags my_module --no-coverage
odoo-dev test                         # Auto-discover & test all addons in addons/ + vendored/
odoo-dev scaffold my_module           # Create a new module

Note: the HTTP port flag is -p / --port (not --http-port).

Database Operations

odoo-dev db list                      # List databases
odoo-dev db restore backup.zip        # Restore from backup (neutralized by default)
odoo-dev db restore backup.zip mydb --no-neutralize
odoo-dev db drop mydb                  # Drop database
odoo-dev db neutralize mydb            # Disable emails/crons

Docker (optional)

odoo-dev docker start                 # Start containers
odoo-dev docker stop                  # Stop containers
odoo-dev docker restart               # Restart containers
odoo-dev docker logs                  # View logs
odoo-dev docker build                 # Rebuild image
odoo-dev docker shell mydb            # Shell in container
odoo-dev docker psql                  # PostgreSQL shell

Setup Commands

odoo-dev setup                        # Full setup (interactive; offers Docker)
odoo-dev setup --community            # Community edition only
odoo-dev setup --no-docker --yes      # Headless/agentic: clone + venv + conf, no Docker, no prompts
odoo-dev setup-venv                   # Just create the venv (no repo clone)
odoo-dev vscode                       # Configure VSCode debugging

Vendored Addons

Shared addons can be vendored — materialized as real committed directories under vendored/, pinned per-addon by addons.lock — instead of pulled in as .repos/ git submodules. This makes each promotion a normal, reviewable file diff and deploys as plain files (what Odoo.sh needs). vendored/ and addons/ are both on the addons path.

odoo-dev vendor migrate               # Convert .repos submodule+symlink addons -> vendored/
odoo-dev vendor migrate --dry-run     # Preview the pins without changing anything
odoo-dev vendor sync                  # Materialize vendored/ from addons.lock
odoo-dev vendor check                 # CI gate: verify vendored/ byte-matches the pins
odoo-dev vendor add fsm --source github.com/bemade/bemade-addons --version 18.0.1.3.2
odoo-dev vendor bump fsm --version 18.0.1.4.0   # Move a pin and re-materialize
odoo-dev vendor update                # Pull newest upstream for all tracked addons
odoo-dev vendor update fsm --dry-run  # Show what would update, change nothing
odoo-dev vendor develop fsm           # Edit fsm against a live source clone
odoo-dev vendor develop fsm --stop    # Leave develop mode (keeps the clone)
odoo-dev vendor status                # Show vendored pins, symlinks, develop mode

Because vendored/<addon> is a materialized copy (re-sync clobbers it), you don't edit it in place. vendor develop <addon> clones the addon's source repo into a git-ignored .vendor-dev/, checks out a work branch at the pinned commit, and prepends an overlay to your local conf/odoo.conf addons_path so Odoo loads the live tree instead of the vendored copy (first path wins). vendored/ stays byte-for-byte pristine and only the local conf is touched, so nothing dev-only can leak into a commit or into CI/prod. Edit in the clone, run/test in this project's Odoo, commit + push upstream, then vendor bump once the new version is tagged. --branch NAME names the work branch; --base REF bases it on something other than the current pin.

vendor check verifies, per addon: the vendored files byte-match the pinned commit; a version tag (if set) still resolves to that commit; every manifest external_dependencies['python'] is named in requirements.txt; no addon name collides between addons/ and vendored/; and no file under vendored/ is gitignored. Python bytecode (__pycache__/, *.pyc) is excluded from the byte comparison, so running the test suite doesn't turn the check red.

That last assertion catches a trap specific to migration: repo-wide ignore rules (node_modules, package.json, …) are harmless while shared addons live in submodules, but they start applying the moment those addons become real files under vendored/ — and git add then skips the matching files without a word, so the committed tree is incomplete while everything looks fine locally. vendor migrate appends a !vendored/** negation to .gitignore when it detects the situation. Pins themselves come from the gitlink the branch records, not from whatever the submodule happens to be checked out at; migrate refuses to run against uninitialized submodules.

vendor update is the pull side: each client owns its pins. For every addon that tracks upstream — a version (bump to the newest <addon>/<version> tag) or a branch (bump to its HEAD) — it moves the pin forward and re-materializes. Addons pinned to a bare commit are left alone. Run it on a schedule (a client's own CI, its own token, opening a vendor-bump/… MR) so shared-addon changes propagate without any per-source push/fan-out machinery.

Project Structure

odoo-dev expects this project structure:

my-odoo-project/
├── .env                 # Optional: ODOO_VERSION, PYTHON_VERSION
├── addons/              # Your custom addons
├── vendored/            # Vendored shared addons (real files, pinned by addons.lock)
├── addons.lock          # Per-addon pins for vendored/ (see `vendor`)
├── requirements.txt     # Project-specific Python deps
├── odoo/                # Cloned by setup
├── enterprise/          # Cloned by setup (unless --community)
├── design-themes/       # Cloned by setup
├── .venv/               # Created by setup
└── conf/
    └── odoo.conf        # Created by setup

vendored/ and addons.lock are only present once a project adopts vendoring (odoo-dev vendor migrate); submodule-based projects use .repos/ + symlinks into addons/ instead.

Configuration

Create a .env file in your project root:

ODOO_VERSION=19.0
PYTHON_VERSION=3.12

# Optional — DB connection, written into conf/odoo.conf by `setup`.
# Omit DB_HOST/DB_PORT to use the local socket (the default). Set these to
# point at a remote / Docker / non-default PostgreSQL:
# DB_HOST=localhost
# DB_PORT=5432
# DB_USER=odoo
# DB_PASSWORD=odoo

Requirements

  • Python 3.12+
  • uv (recommended) or pip
  • Git
  • PostgreSQL (for local development — server + an odoo role; see "Database setup")
  • Docker (optional, for containerized development)

Development

# Clone and install for development
git clone git@github.com:bemade/odoo-dev.git
cd odoo-dev
uv sync

# Run tests
uv run pytest                 # All tests
uv run pytest -m "not slow"   # Fast tests only

# Build
uv build

License

LGPL-3. For complete license terms, visit https://www.gnu.org/licenses/lgpl-3.0.en.html

Release files for odoo-dev 1.2.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for odoo-dev 1.2.3
File Size Uploaded
odoo_dev-1.2.3.tar.gz 80.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for odoo-dev 1.2.3
File Interpreter ABI Platform
odoo_dev-1.2.3-py3-none-any.whl Python 3 none any Details

Total release size: 138.6 kB

Release files / odoo_dev-1.2.3.tar.gz

Download URL odoo_dev-1.2.3.tar.gz
Size 80.3 kB
Tags Source
SHA-256 checksum
How to use checksums
f09ec3f414df234203f4c7dd30f0a67293bd3cac1d8ce1c6c84af2748ba9823b
BLAKE2b-256 checksum
How to use checksums
e770279fd96439dc044226b293b37100acc602a8aa2e368c25327c09f8538f32
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / odoo_dev-1.2.3-py3-none-any.whl

Download URL odoo_dev-1.2.3-py3-none-any.whl
Size 58.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
be9a6155b57f4ad127b10e5083b874421db1a5bb2d7da5465a5985679766fafe
BLAKE2b-256 checksum
How to use checksums
7fe5a8a2e0481351f9f4bf068e704b239a211ec434e8ade2e2a1a6cd805413a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

1.4.0

2 release files

1.3.0

2 release files

This release

1.2.3 This release

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.4.0

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page