A set of DevOps tools for Odoo deployments and local dev.
Project description
odoo-devops-tools
A set of DevOps tools for Odoo deployments and local dev.
Installation
Install with pip:
pip install odoo-devops-tools
Or install with uv:
uv tool install odoo-devops-tools
odt-env --help
Command: odt-env
Provision and sync a reproducible Odoo workspace from an INI configuration file.
Requirements
Usage
Full default behavior (clone repositories, create venv, generate config and helper scripts):
odt-env /path/to/ROOT/odoo-project.ini --sync-all --create-venv
By default, ROOT is the directory containing the INI file. You can override where the workspace is created with --root (must point to an existing directory):
odt-env /path/to/odoo-project.ini --sync-all --create-venv --root /path/to/NEW-ROOT
If you want to build the workspace in one location but have the generated configs/scripts refer to a different deployment root, use --dest-root. This path does not need to exist on the build machine (it may only exist on the target host):
odt-env /path/to/odoo-project.ini --sync-all --create-wheelhouse --root /tmp/build-root --dest-root /srv/odoo/myproject
Sync without venv provisioning:
odt-env /path/to/ROOT/odoo-project.ini --sync-all
Build wheelhouse without venv provisioning:
odt-env /path/to/ROOT/odoo-project.ini --sync-all --create-wheelhouse
Offline venv provisioning from an existing wheelhouse:
odt-env /path/to/ROOT/odoo-project.ini --create-venv --reuse-wheelhouse
Hard rebuild of the venv:
odt-env /path/to/ROOT/odoo-project.ini --sync-all --rebuild-venv
If no options are specified, odt-env only regenerates config and helper scripts:
odt-env /path/to/ROOT/odoo-project.ini
What odt-env creates (directory layout)
ROOT is the directory containing odoo-project.ini (or the path passed via --root).
If you pass --dest-root, odt-env still creates files under ROOT, but paths embedded inside generated files are based on DEST_ROOT.
ROOT/odoo/- Odoo repositoryROOT/odoo-addons/<name>/- addon repositoriesROOT/odoo-backups/- backups directoryROOT/odoo-data/- data directory (can be customized via[config] data_dirin the INI file).ROOT/odoo-configs/- generatedodoo-server.confROOT/odoo-scripts/- helper scripts (see below)ROOT/odoo-logs/- runtime logs (created byinstance.sh)ROOT/venv/- Virtualenv / Python toolchain (created/updated with--create-venv/--rebuild-venv/--create-wheelhouse).ROOT/wheelhouse/- Local cache of python packages in wheel format (created/updated with--create-venv/--rebuild-venv/--create-wheelhouse)
Example configuration
This configuration creates a ready-to-run Odoo 18.0 development workspace, including:
- Python 3.11 virtual environment (
ROOT/venv/) - Odoo 18.0 checkout (
ROOT/odoo/) - Addons checkouts (
ROOT/odoo-addons/oca-web/andROOT/odoo-addons/oca-helpdesk/)
[virtualenv]
python_version = 3.11
# Optional (default: true): when false, odt-env will NOT install a managed CPython via `uv python install`.
# Instead it will rely on an existing system Python that matches `python_version`.
# managed_python = false
build_constraints =
requirements =
requirements_ignore =
[odoo]
repo = https://github.com/odoo/odoo.git
branch = 18.0
# Optional: If true, keep repo as a shallow, single-branch clone (depth=1). If false (default), do a full clone/fetch.
shallow_clone = true
[addons.oca-web]
repo = https://github.com/OCA/web.git
branch = 18.0
[addons.oca-helpdesk]
repo = https://github.com/OCA/helpdesk.git
branch = 18.0
[config]
http_port = 8069
gevent_port = 8072
db_host = 127.0.0.1
db_port = 5432
db_name = sample_odoo18
db_user = sample_odoo18
db_password = sample_odoo18
log_level = debug
max_cron_threads = 0
Using multiple configuration files with inheritance
odt-env supports a lightweight include mechanism so you can split configuration across multiple INI files (for example a shared base.ini plus a local override file).
Notes:
- Paths are resolved relative to the INI file that declares the include.
- Included files are loaded first; the including file is loaded last (later values override earlier ones).
- Prefix a path with
?to make it optional (missing file is skipped).
Example:
odoo-base.ini:
[virtualenv]
python_version = 3.11
build_constraints =
requirements =
requirements_ignore =
[odoo]
repo = https://github.com/odoo/odoo.git
branch = 18.0
[config]
http_port = 8069
gevent_port = 8072
db_host = 127.0.0.1
db_port = 5432
db_name = sample_odoo18
db_user = sample_odoo18
db_password = sample_odoo18
odoo-dev.ini:
[include]
files = odoo-base.ini
[odoo]
branch = develop
[config]
db_name = sample_odoo18_dev
odoo-test.ini:
[include]
files =
odoo-base.ini
?odoo-dev.ini
[config]
db_name = sample_odoo18_test
Configuration variables & interpolation
odt-env uses Python's ExtendedInterpolation, so you can reference values via ${section:option} (for example ${vars:branch}).
In addition, odt-env injects a set of runtime variables (workspace paths) into the INI DEFAULT scope, so they are available from any section in the INI file:
${ini_dir}- directory containing the INI file${root_dir}- workspace root directory${odoo_dir}-ROOT/odoo${addons_dir}-ROOT/odoo-addons${backups_dir}-ROOT/odoo-backups${configs_dir}-ROOT/odoo-configs${config_path}- full path to the generatedodoo-server.conf${scripts_dir}-ROOT/odoo-scripts${venv_python}- full path to the virtualenv Python executable
Note on --dest-root:
- odt-env always builds under
ROOT(filesystem workspace). - When
--dest-rootis provided, values like${root_dir},${odoo_dir},${addons_dir}etc. are evaluated againstDEST_ROOTfor the[config]section (used to render generated files likeodoo-server.conf). - Other sections (for example
[odoo],[addons.*],[virtualenv]) continue to use the filesystemROOTso build-time operations (git/venv/wheelhouse) are unaffected. ${ini_dir}always points to the directory containing the entry INI on the build machine (needed for includes).
Tip: You can define your own helper section (for example [vars]) and reuse it across other sections.
Example:
[vars]
project = sample_odoo18
branch = 18.0
[virtualenv]
python_version = 3.11
requirements =
-r ${ini_dir}/requirements-dev.txt
[odoo]
repo = https://github.com/odoo/odoo.git
branch = ${vars:branch}
[addons.oca-web]
repo = https://github.com/OCA/web.git
branch = ${odoo:branch}
[config]
db_name = ${vars:project}
data_dir = ${root_dir}/odoo-data/${vars:project}
logfile = ${root_dir}/odoo-logs/${vars:project}.log
Extending addons_path
odt-env always generates an addons_path for odoo-server.conf that includes:
- Odoo core addons directory (
ROOT/odoo/addonsand/orROOT/odoo/odoo/addons) - every synced addon repository (
ROOT/odoo-addons/<name>)
If you specify addons_path in the INI [config] section, it extends (appends to) this computed base list (it does not replace it). Duplicates are removed.
Format details:
- you can use a comma-separated list and/or a multi-line value
- relative paths are resolved relative to
ROOT(same as${root_dir})
Example:
[config]
addons_path =
odoo-addons/3rd_party_addons,
${addons_dir}/extra_addons,
Shallow clones (shallow_clone)
By default, odt-env keeps repositories as full clones (all branches + tags + full history). For very large repositories (especially odoo/odoo) you can enable a shallow, single-branch workflow.
Where to set it:
[odoo] shallow_clone = true(Odoo core repo)[addons.<name>] shallow_clone = true(per addon repo)
What it does when enabled:
- initial clone:
git clone --depth 1 --single-branch --branch <branch> ... - sync/update: fetch only
origin <branch>with--depth 1, then force local<branch>to matchorigin/<branch>(hard reset) - no
git fetch --all; other branches are not kept locally, and tags are not fetched broadly
Pros:
- much faster clone/fetch
- significantly less disk usage
Limitations / gotchas:
- depth is fixed to 1 (only the tip of the branch is available)
- git operations that require history (for example long
git log,git bisect,git describeon older tags/commits) will not work as expected - if you need to work across multiple branches, keep
shallow_clone = false - switching from a full clone to
shallow_clone = truedoes not automatically drop existing history; to actually get the disk/speed benefits, delete the repo directory (ROOT/odooorROOT/odoo-addons/<name>) and re-sync.
Switching back to a full clone:
Set shallow_clone = false (or remove it) and re-run a sync. If the repo is shallow and/or single-branch, odt-env automatically converts it back to full history (unshallow) and widens the origin fetch refspec so a subsequent fetch --all --tags can pull all remote branches.
Command-line Options
--root- override workspace ROOT directory (default: directory containing INI)--dest-root- override DEST_ROOT used for paths embedded in generated configs/scripts (default: same as ROOT; DEST_ROOT does not need to exist on the build machine)--sync-odoo- sync onlyROOT/odoo--sync-addons- sync onlyROOT/odoo-addons/*(optional; if there are no[addons.*]sections in the INI, this is a no-op)--sync-all- sync both--create-venv- enable virtualenv provisioning: create/updateROOT/venvand install Python dependencies (from the wheelhouse).--rebuild-venv- deleteROOT/venvand recreate it (implies--create-venv).--reuse-wheelhouse- reuse an existingROOT/wheelhouse/and install offline only (skip lock/wheel build). Requires--create-venv.--create-wheelhouse- build/update the lock file +ROOT/wheelhouse/without installing project requirements into the venv. (odt-env may create/updateROOT/venv/as a Python toolchain.)--clear-pip-wheel-cache- remove all items from the pip's wheel cache.--no-configs- don’t generate config files (e.g.ROOT/odoo-configs/odoo-server.conf).--no-scripts- don’t generate helper scripts underROOT/odoo-scripts/.--no-data-dir- don’t create the Odoo data folder underROOT/odoo-data/(or a custom path set via[config] data_dirin the INI file).
If no options are specified, odt-env only regenerates configs and helper scripts.
Virtualenv
odt-env installs project Python dependencies into the venv only when you pass --create-venv (or --rebuild-venv).
You can (re)build the ROOT/wheelhouse/ either as part of venv provisioning, or separately with --create-wheelhouse.
- The venv is created/used at:
ROOT/venv - Python version is taken from:
[virtualenv] python_version - venv + installs are done via:
uv venvanduv pip - If the requested Python version is not available on the machine and managed Python is enabled, odt-env installs it via
uv python install. - Requirements are resolved into a single lock file and installed into the venv from
ROOT/wheelhouse/using offline mode (--offline --no-index).
Reusing an existing wheelhouse
If ROOT/wheelhouse/ is already prepared (wheels + all-requirements.lock.txt), you can run (requires --create-venv):
odt-env /path/to/odoo-project.ini --create-venv --reuse-wheelhouse
This skips lock compilation and wheel building and does a strict offline install from the wheelhouse.
It also works together with --sync-all/--sync-odoo/--sync-addons (repo sync still happens, but python deps are installed
from the existing lock/wheels).
Managed Python Install
By default, odt-env manages the requested CPython version for you using uv.
- Option:
[virtualenv] managed_python - Default:
true(you can omit it)
Behavior:
managed_python = true(default): when odt-env needs to createROOT/venv/, it ensures the requestedpython_versionexists by runninguv python install.managed_python = false: odt-env skipsuv python installand relies on an already-installed system Python that matchespython_version. If such Python is not available, venv creation will fail.
Example:
[virtualenv]
python_version = 3.11
managed_python = false
Safety / local changes policy
If any target repository (Odoo or an addon) contains local uncommitted changes (including untracked files), odt-env aborts. Commit/stash/clean your working tree before running odt-env.
Generated scripts
odt-env generates helper scripts into ROOT/odoo-scripts/. All scripts use the generated configuration file (odoo-configs/odoo-server.conf) and forward any additional arguments to the underlying command.
Linux/macOS
ROOT/odoo-scripts/run.shROOT/odoo-scripts/instance.shROOT/odoo-scripts/test.shROOT/odoo-scripts/shell.shROOT/odoo-scripts/initdb.shROOT/odoo-scripts/backup.shROOT/odoo-scripts/restore.shROOT/odoo-scripts/restore_force.shROOT/odoo-scripts/update.shROOT/odoo-scripts/update_all.sh
Windows
ROOT/odoo-scripts/run.batROOT/odoo-scripts/test.batROOT/odoo-scripts/shell.batROOT/odoo-scripts/initdb.batROOT/odoo-scripts/backup.batROOT/odoo-scripts/restore.batROOT/odoo-scripts/restore_force.batROOT/odoo-scripts/update.batROOT/odoo-scripts/update_all.bat
1. Start the Odoo server
Starts the Odoo server.
Linux/macOS
./odoo-scripts/run.sh
Windows
odoo-scripts\run.bat
1a. Manage the Odoo server instance (Linux only)
Starts/stops Odoo in the background and writes logs into ROOT/odoo-logs/odoo-server.log (the ROOT/odoo-logs/ directory is created automatically if it doesn't exist).
Supported commands: start, stop, restart, status.
statusprints the PID if the server is running (exit code 0), otherwise printsNOT RUNNING(exit code 1).startaccepts additional arguments, which are forwarded toodoo-bin.
Linux/macOS
./odoo-scripts/instance.sh start
./odoo-scripts/instance.sh status
./odoo-scripts/instance.sh restart
./odoo-scripts/instance.sh stop
2. Update modules
Update an Odoo database (odoo -u), automatically detecting addons to update based on a hash of their file content, compared to the hashes stored in the database
Linux/macOS
./odoo-scripts/update.sh
Windows
odoo-scripts\update.bat
3. Update all modules
Force a complete upgrade (-u base)
Linux/macOS
./odoo-scripts/update_all.sh
Windows
odoo-scripts\update_all.bat
4. Run tests
Runs Odoo tests.
Linux/macOS
./odoo-scripts/test.sh -u base
./odoo-scripts/test.sh -u mail,web
./odoo-scripts/test.sh -u my_custom_addon
Windows
odoo-scripts\test.bat -u base
odoo-scripts\test.bat -u mail,web
odoo-scripts\test.bat -u my_custom_addon
5. Open an Odoo shell
Opens an interactive Odoo shell.
Linux/macOS
./odoo-scripts/shell.sh
Windows
odoo-scripts\shell.bat
6. Initialize the database
Create or initialize an Odoo database with pre-installed modules
Linux/macOS
./odoo-scripts/initdb.sh
Windows
odoo-scripts\initdb.bat
7. Create a database backup
Creates a timestamped ZIP backup of the database into ROOT/odoo-backups/.
This script dumps the database using pg_dump.
It also copies the filestore
Linux/macOS
./odoo-scripts/backup.sh
Windows
odoo-scripts\backup.bat
8. Restore a database backup
Restores a database from a given backup. Neutralizing a database as well
Linux/macOS
./odoo-scripts/restore.sh PATH/TO/BACKUP.zip
Windows
odoo-scripts\restore.bat PATH\TO\BACKUP.zip
9. Restore a backup (force)
Same as restore, but overwrites an existing database
Linux/macOS
./odoo-scripts/restore_force.sh PATH/TO/BACKUP.zip
Windows
odoo-scripts\restore_force.bat PATH\TO\BACKUP.zip
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file odoo_devops_tools-1.0.1.tar.gz.
File metadata
- Download URL: odoo_devops_tools-1.0.1.tar.gz
- Upload date:
- Size: 31.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0642702d783b945307e6c630d5614336167e7c2c27b862718d492b384e4b50bc
|
|
| MD5 |
1454290e95c553ad9ad117d361cc14e0
|
|
| BLAKE2b-256 |
85eb570606ea2aa3f0449e8dfa9a36b538ced99b527580abc57bec0beca837b5
|
File details
Details for the file odoo_devops_tools-1.0.1-py3-none-any.whl.
File metadata
- Download URL: odoo_devops_tools-1.0.1-py3-none-any.whl
- Upload date:
- Size: 26.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06b1db5992ec5b77ef33282ac333718e07cee4a1b0b57de10ab0a1f3d9a7f336
|
|
| MD5 |
b593cc267bc46fcb6d77ff83e135fb22
|
|
| BLAKE2b-256 |
c4d56c925d0064c285b58b1258c057dd9b098b081f538a78b18a1396e79dad0a
|