odoo-devops-tools
Manage reproducible Odoo workspaces.
odoo-devops-tools provides odt-env, a CLI for creating reproducible Odoo workspaces from a single configuration file.
A basic workspace definition with addons can look like this:
[odoo]
version = 19.0
[addons.oca-web]
repo = https://github.com/OCA/web.git
branch = ${odoo:version}
[addons.oca-helpdesk]
repo = https://github.com/OCA/helpdesk.git
branch = ${odoo:version}
From this configuration, odt-env can generate a workspace such as:
ROOT/
├── docker/ # generated Docker artifacts
│ ├── local/ # Docker workflow artifacts
│ │ └── scripts/ # database and filestore backup/restore helpers
│ └── deploy/ # self-contained deploy build context
├── odoo/ # Odoo source
├── odoo-addons/ # addon sources
│ ├── oca-web/
│ └── oca-helpdesk/
├── odoo-configs/ # generated Odoo configuration
├── odoo-scripts/ # run, test, shell, backup, restore, update
├── odoo-data/ # Odoo data directory
├── odoo-logs/ # runtime logs
├── odoo-backups/ # backups created by helper scripts
├── wheelhouse/ # offline Python wheelhouse
├── venv/ # Python virtual environment
├── compose.yaml # Docker Compose file
└── odoo-project.ini # workspace configuration
Key features
- Reproducible workspaces — define and recreate an Odoo workspace from a single INI configuration.
- Docker workflows — generate local Docker Compose environments and self-contained deploy build contexts.
- Portable workflows — create verified bundles with sources and Python wheels for reproducible or offline use.
- Python dependency management — manage Python versions, virtual environments and requirements.
- Composable configuration — combine INI layers, variables, and CLI overrides.
odt-env focuses on creating and maintaining the Odoo workspace and its derived artifacts. Infrastructure provisioning and deployment orchestration remain outside its scope.
System requirements
- git: https://git-scm.com/install/
- uv: https://docs.astral.sh/uv/getting-started/installation/
- Docker: https://docs.docker.com/get-docker/ — optional, for Docker workflows.
Installation
Install the CLI with uv:
uv tool install -U odoo-devops-tools
Verify the installation:
odt-env --help
Quick start
odt-env supports two development workflows:
- Docker workflow — run Odoo and PostgreSQL with the generated Docker Compose environment.
- Native development with venv — run Odoo directly on the host using a generated Python virtual environment.
Choose the workflow that fits your environment. Both use the same odoo-project.ini project definition.
Docker workflow
Create a new workspace:
odt-env --init-project ./odoo19
Start the Docker Compose environment:
cd ./odoo19
docker compose up -d
Initialize the Odoo database:
docker compose run --rm odoo -- -c /etc/odoo/odoo.conf -d odoo \
-i base \
--without-demo=all \
--stop-after-init
Docker Compose runs both Odoo and PostgreSQL. Odoo is available at http://localhost:8069.
Native development with venv
In this workflow, Odoo runs directly on the host using a generated Python virtual environment.
Create the workspace with the Odoo source and virtual environment:
odt-env --init-project ./odoo19 --sync-all --create-venv \
--set config:db_host=127.0.0.1 \
--set config:db_name=odoo \
--set config:db_user=odoo \
--set config:db_password=odoo
Note Make sure PostgreSQL is running at the configured host and the configured database user exists.
Start Odoo with the generated script:
cd ./odoo19
./odoo-scripts/run.sh
Odoo starts with the generated configuration from ./odoo-configs/odoo-server.conf and is available at http://localhost:8069.
Usage
The examples below use the workspace configuration introduced in the Quick start section.
1. Docker workflow
The Docker workflow uses the following odoo-project.ini configuration:
[virtualenv]
managed_python = true
python_version =
build_constraints =
requirements =
requirements_ignore =
[odoo]
version = 19.0
repo = https://github.com/odoo/odoo.git
branch = 19.0
commit =
shallow = true
[docker]
base_image = odoo:19.0
[config]
Edit this file when you want to add extra addons, change configuration values, pin repositories, or adjust Python dependency handling.
1.1. Adding extra addons
To extend Odoo with additional functionality, add extra addons through [addons.<name>] sections in odoo-project.ini.
In this example, we add two Git-based addon repositories, OCA/web and OCA/helpdesk.
1.1.1. Update the project file
Edit odoo-project.ini in the workspace root and add these addon sections:
[addons.oca-web]
repo = https://github.com/OCA/web.git
branch = ${odoo:version}
[addons.oca-helpdesk]
repo = https://github.com/OCA/helpdesk.git
branch = ${odoo:version}
The rest of the generated project file can stay unchanged.
1.1.2. Sync and install addons
Sync the configured addon repositories and refresh the generated Docker workflow artifacts:
odt-env --sync-addons
docker compose up --build -d
The addon repositories are cloned into ROOT/odoo-addons/oca-web/ and ROOT/odoo-addons/oca-helpdesk/ and bind-mounted into the Odoo container.
If an addon source contains a requirements.txt file, its Python dependencies are included when the Docker image is rebuilt.
Install the modules from the newly added addon repositories:
docker compose run --rm odoo -- -c /etc/odoo/odoo.conf -d odoo \
-i web_notify,helpdesk_mgmt \
--without-demo=all \
--stop-after-init
For subsequent addon updates, run click-odoo-update inside the Odoo container:
docker compose exec odoo click-odoo-update -c /etc/odoo/odoo.conf -d odoo
1.2. Backup and restore
The Docker workflow generates Unix shell helpers under ROOT/docker/local/scripts/ for backing up and restoring the PostgreSQL database and Odoo filestore independently:
docker/local/scripts/
├── backup-db.sh
├── restore-db.sh
├── backup-filestore.sh
├── restore-filestore.sh
├── restic.sh
├── backup-filestore-restic.sh
└── restore-filestore-restic.sh
The helpers stream backup data directly between the Docker containers and files on the host. No backup directory is mounted into the containers, and no intermediate backup file is created inside a container.
The default database name is taken from [config].db_name when configured, otherwise it is odoo. Override it for any command with ODOO_DB_NAME:
ODOO_DB_NAME=odoo_test ./docker/local/scripts/backup-db.sh
1.2.1. Database backup
Create a PostgreSQL custom-format dump under ROOT/odoo-backups/:
./docker/local/scripts/backup-db.sh
The default output name is timestamped, for example:
odoo-backups/odoo_20260923_093000.dump
Pass an output path explicitly when needed:
./docker/local/scripts/backup-db.sh ./odoo-backups/pre-upgrade.dump
1.2.2. Database restore
Restore a database dump with pg_restore:
./docker/local/scripts/restore-db.sh ./odoo-backups/pre-upgrade.dump
The target database is dropped and recreated before the dump is restored. When restoring the database currently used by the Odoo service, stop Odoo first and start it again after the restore:
docker compose stop odoo
./docker/local/scripts/restore-db.sh ./odoo-backups/pre-upgrade.dump
docker compose up -d odoo
To restore the same dump into another database without replacing the default database:
ODOO_DB_NAME=odoo_restore ./docker/local/scripts/restore-db.sh ./odoo-backups/pre-upgrade.dump
1.2.3. Filestore backup
Create a compressed tar archive of the selected database filestore:
./docker/local/scripts/backup-filestore.sh
The default output name is timestamped, for example:
odoo-backups/odoo_20260923_093000_filestore.tar.gz
Pass an output path explicitly when needed:
./docker/local/scripts/backup-filestore.sh ./odoo-backups/pre-upgrade-filestore.tar.gz
The helper uses a one-off Odoo container with the same odoo-data volume, so the main Odoo service does not need to be running.
When creating a matching database and filestore backup for migration or disaster recovery, stop Odoo first to prevent writes while both parts are captured:
docker compose stop odoo
./docker/local/scripts/backup-db.sh ./odoo-backups/pre-upgrade.dump
./docker/local/scripts/backup-filestore.sh ./odoo-backups/pre-upgrade-filestore.tar.gz
docker compose up -d odoo
1.2.4. Filestore restore
Restore a filestore archive:
./docker/local/scripts/restore-filestore.sh ./odoo-backups/pre-upgrade-filestore.tar.gz
The existing filestore directory for the target database is removed before the archive is extracted. When restoring the filestore currently used by the Odoo service, stop Odoo first:
docker compose stop odoo
./docker/local/scripts/restore-filestore.sh ./odoo-backups/pre-upgrade-filestore.tar.gz
docker compose up -d odoo
A filestore can also be restored under another database name:
ODOO_DB_NAME=odoo_restore ./docker/local/scripts/restore-filestore.sh ./odoo-backups/pre-upgrade-filestore.tar.gz
Database and filestore backups are intentionally separate. This allows either part to be restored independently while still making it possible to create matching database and filestore backups when both are needed.
1.2.5. Restic filestore backup
The generated Docker image also includes restic, installed from the base image APT repositories. Restic is an additional option intended especially for large filestores where incremental snapshots and deduplication are useful.
The Docker workflow generates three additional helpers:
docker/local/scripts/restic.sh
docker/local/scripts/backup-filestore-restic.sh
docker/local/scripts/restore-filestore-restic.sh
restic.sh is a generic wrapper that runs the restic binary from the generated Odoo image against the same odoo-data volume. The restic cache is kept under /var/lib/odoo/.cache/restic, outside the filestore directory, so it persists between one-off containers without being included in filestore backups.
Set RESTIC_REPOSITORY and either RESTIC_PASSWORD_FILE or RESTIC_PASSWORD before using the helpers. For a local repository on the Docker host, use an absolute path. The wrapper automatically bind-mounts that path into the one-off container:
export RESTIC_REPOSITORY=/srv/restic/odoo
export RESTIC_PASSWORD_FILE=/etc/restic/odoo-password
./docker/local/scripts/restic.sh init
A remote restic repository URL can be used instead of a local path. Backend-specific authentication or external helper programs, when required by that backend, must also be made available to the container.
Create a restic snapshot of the selected database filestore:
./docker/local/scripts/backup-filestore-restic.sh
The default database name follows the same ODOO_DB_NAME convention as the archive helpers. Snapshots are tagged with odoo, filestore, and db:<database>. The helper also uses a stable host identifier from the Docker host for restic snapshot grouping; override it with RESTIC_HOST when needed.
An optional backup identifier can be added as another snapshot tag:
RESTIC_BACKUP_ID=20260923_020000 ./docker/local/scripts/backup-filestore-restic.sh
This is useful for pairing a PostgreSQL dump with the corresponding filestore snapshot.
List or inspect snapshots through the generic wrapper:
./docker/local/scripts/restic.sh snapshots
./docker/local/scripts/restic.sh check
1.2.6. Restic filestore restore
Restore the latest matching filestore snapshot:
docker compose stop odoo
./docker/local/scripts/restore-filestore-restic.sh
docker compose up -d odoo
Or restore a specific snapshot ID:
docker compose stop odoo
./docker/local/scripts/restore-filestore-restic.sh SNAPSHOT_ID
docker compose up -d odoo
To restore a filestore backed up under one database name into another database, set the target with ODOO_DB_NAME and the source snapshot path with RESTIC_SOURCE_DB_NAME:
ODOO_DB_NAME=odoo_restore RESTIC_SOURCE_DB_NAME=odoo ./docker/local/scripts/restore-filestore-restic.sh SNAPSHOT_ID
The restore helper removes the target database filestore before restoring it. When latest is used, the snapshot selection is restricted to the current RESTIC_HOST and source filestore path. Use the same RESTIC_HOST value that was used when the snapshot was created if the restore is performed from another host.
1.3. Creating a Docker deploy build context
Use --create-docker-deploy to generate a self-contained Docker build context for CI/CD, testing, staging, production, or another non-local deployment workflow.
Addon modules are staged into the build context so the resulting image does not depend on bind-mounted workspace sources:
odt-env --sync-addons --create-docker-deploy
This additionally creates:
ROOT/docker/deploy/
├── Dockerfile
├── .dockerignore
├── addons/
├── requirements/
└── configs/
└── odoo.conf
Addon modules are staged under docker/deploy/addons/ and copied into /mnt/extra-addons/ by the generated Dockerfile. Runtime Compose configuration is not generated for the deploy context.
odt-env prepares the deploy build context but does not build or push the image. Build it with Docker or your CI/CD system, for example:
docker build -t mycompany/odoo:19.0 docker/deploy
[docker].base_image controls the base image used by both generated Dockerfiles.
In CI, where the docker/local/ context is unnecessary, combine the options:
odt-env --sync-addons --create-docker-deploy --no-local-docker
docker build -t mycompany/odoo:19.0 docker/deploy
2. Native development with venv
The native workflow uses the following odoo-project.ini configuration, with PostgreSQL connection settings added to [config]:
[virtualenv]
managed_python = true
python_version =
build_constraints =
requirements =
requirements_ignore =
[odoo]
version = 19.0
repo = https://github.com/odoo/odoo.git
branch = 19.0
commit =
shallow = true
[docker]
base_image = odoo:19.0
[config]
db_host = 127.0.0.1
db_name = odoo
db_user = odoo
db_password = odoo
Edit this file when you want to add extra addons, change configuration values, pin repositories, or adjust Python dependency handling.
2.1. Adding extra addons
To extend Odoo with additional functionality, add extra addons through [addons.<name>] sections in odoo-project.ini.
In this example, we add two Git-based addon repositories, OCA/web and OCA/helpdesk.
2.1.1. Update the project file
Edit odoo-project.ini in the workspace root and add these addon sections:
[addons.oca-web]
repo = https://github.com/OCA/web.git
branch = ${odoo:version}
[addons.oca-helpdesk]
repo = https://github.com/OCA/helpdesk.git
branch = ${odoo:version}
The rest of the generated project file can stay unchanged.
2.1.2. Sync and install addons
Sync the sources and recreate the Python environment so dependencies from the new addon repositories are included:
odt-env --sync-all --create-venv
The addon repositories are cloned into ROOT/odoo-addons/oca-web/ and ROOT/odoo-addons/oca-helpdesk/, and their directories are added to the generated addons_path.
Start Odoo and install the modules from the newly added addon repositories:
./odoo-scripts/run.sh -i web_notify,helpdesk_mgmt
For subsequent addon updates, use the generated update script:
./odoo-scripts/update.sh
The generated script uses click-odoo-update with the workspace Odoo configuration.
2.2. Using system Python instead of managed Python
By default, odt-env uses uv to install and manage the requested Python version.
If you already have a suitable system Python installed, you can disable managed Python.
2.2.1. Update the project file
Disable managed Python by adding python_version = 3.11 and managed_python = false to the odoo-project.ini file.
Note Set
python_versionto the Python version you want to use from your local system. In the example below, 3.11 is only illustrative.
[virtualenv]
managed_python = false
python_version = 3.11
2.2.2. Update the workspace
After changing the project file, run odt-env again from the workspace root:
odt-env --sync-all --create-venv
This recreates the virtual environment at ROOT/venv using the system Python.
2.3. Script reference
This section describes the native helpers under ROOT/odoo-scripts/. Docker backup/restore helpers are documented in the Docker workflow section above.
Most helper scripts are generated in both Unix (.sh) and Windows (.bat) variants. instance.sh is available only on Unix-like systems.
Native database backup and restore scripts are generated only when [config].db_name is configured.
The examples below use the Unix form.
2.3.1. run
Starts Odoo in the foreground.
Any extra arguments are forwarded to the underlying command odoo-bin.
Examples:
./odoo-scripts/run.sh
./odoo-scripts/run.sh --dev=all
./odoo-scripts/run.sh -i sale,crm --without-demo=all
2.3.2. instance
Manages Odoo as a background service on Unix-like systems.
Logs are written to ROOT/odoo-logs/odoo-server.log and the PID is stored in ROOT/odoo-logs/odoo-server.pid.
Examples:
./odoo-scripts/instance.sh start
./odoo-scripts/instance.sh stop
./odoo-scripts/instance.sh restart
./odoo-scripts/instance.sh status
2.3.3. test
Runs Odoo tests.
The script always adds --test-enable --stop-after-init.
Any extra arguments are forwarded to the underlying command odoo-bin.
Examples:
./odoo-scripts/test.sh
./odoo-scripts/test.sh -i sale --test-tags /sale
2.3.4. shell
Opens an Odoo shell.
Examples:
./odoo-scripts/shell.sh
2.3.5. backup
Creates a timestamped ZIP backup under ROOT/odoo-backups/.
Any extra arguments are forwarded to the underlying command click-odoo-backupdb from click-odoo-contrib package.
Examples:
./odoo-scripts/backup.sh
2.3.6. restore
Restores a backup into the configured database.
The script always adds --copy --neutralize.
Any extra arguments are forwarded to the underlying command click-odoo-restoredb from click-odoo-contrib package.
Examples:
./odoo-scripts/restore.sh ./odoo-backups/odoo_20260331_221443.zip
./odoo-scripts/restore.sh ./odoo-backups/odoo_20260331_221443.zip --force
2.3.7. update
Updates an Odoo database automatically detecting addons to update based on a hash of their file content.
Any extra arguments are forwarded to the underlying command click-odoo-update from click-odoo-contrib package.
Examples:
./odoo-scripts/update.sh
./odoo-scripts/update.sh --update-all
3. Managing Python requirements
The [virtualenv] section controls additional Python dependencies used when provisioning both the native virtual environment and generated Docker images.
Use it to add new packages, pin specific versions, and override packages collected from Odoo or addon repository requirements.txt files.
Use:
requirementsto add extra packages or pin an explicit versionrequirements_ignoreto skip packages that would otherwise be collected from repository requirements files
When a package is listed in requirements, odt-env automatically gives that package priority by ignoring the same package name from collected repository requirements. This means you can usually pin a package version just by adding it to requirements.
3.1. Add or pin packages
Use requirements to install additional packages or to force a specific version:
[virtualenv]
requirements =
requests==2.32.3
boto3==1.35.99
In this example, both packages are included in the generated dependency set and pinned to the specified versions.
3.2. Override a package with a different one
If you want to replace a package with a different distribution name, add the replacement to requirements and skip the original package with requirements_ignore.
Example:
[virtualenv]
requirements =
psycopg2-binary==2.9.9
requirements_ignore =
psycopg2
In this example, odt-env installs psycopg2-binary==2.9.9 and skips psycopg2 when collecting repository requirements.
4. Creating portable workspace bundles
Portable bundles are useful when you want to prepare an Odoo workspace on an internet-connected machine and reproduce it on another compatible machine without cloning repositories or downloading Python packages again.
A portable workspace bundle is a ZIP archive containing:
odoo/
odoo-addons/
wheelhouse/
manifest.json
odoo-project.ini
The bundle does not contain the virtual environment, database data, logs, backups, generated scripts, generated configuration files, Docker artifacts, Git metadata, or provisioning history.
Those machine-specific outputs are recreated on the target machine.
4.1. Create a bundle on the build machine
On an internet-connected build machine, sync the sources, build the wheelhouse, and create the bundle in one command:
odt-env --sync-all --create-venv --create-bundle
When no output path is supplied, the bundle is written to:
ROOT/dist/ROOT-NAME.odt.zip
You can also select an explicit output file:
odt-env --sync-all --create-venv --create-bundle ./artifacts/odoo18-production.odt.zip
4.1.1. Including uncommitted changes
By default, bundle creation stops when a bundled Git repository has uncommitted changes.
To intentionally include those changes in the bundle, use:
odt-env --sync-all --create-venv --create-bundle --allow-dirty-bundle
4.2. Create the workspace on the target machine
Copy the ZIP to the target machine and import it into an empty directory:
odt-env --create-from-bundle ./odoo18-production.odt.zip \
--root ./odoo18-prod \
--set config:db_host=127.0.0.1 \
--set config:db_name=odoo \
--set config:db_user=odoo \
--set config:db_password=odoo
The import operation:
- verifies the bundle format, platform, and CPU architecture;
- rejects unsafe ZIP paths, duplicate entries, and symbolic links;
- verifies every bundled file using its size and SHA-256 checksum;
- extracts Odoo, addons, the sanitized project INI, and the wheelhouse;
- recreates
ROOT/venvstrictly from the bundled wheelhouse; - regenerates configuration files and helper scripts.
ROOT must be empty. If --root is omitted, the current working directory is used and must be empty. The imported manifest is saved as ROOT/.odt-env/imported-bundle-manifest.json.
Compatibility note A wheelhouse is platform- and architecture-dependent. Create and import a bundle on compatible systems, for example Linux x86-64 to Linux x86-64. The target machine must have
uvand access to the configured Python version. When[virtualenv].managed_python = true,uvmay still need network access if that Python interpreter is not already installed or cached. For a fully disconnected target, install the required Python interpreter beforehand or usemanaged_python = false.
4.3. Manual wheelhouse workflow
The existing manual workflow remains available. After preparing a complete workspace on the build machine, copy the whole workspace and run this command from the copied root:
odt-env --create-venv-from-wheelhouse --no-local-docker
This recreates ROOT/venv, skips dependency compilation and wheelhouse building, and installs strictly from the existing ROOT/wheelhouse/ and all-requirements.lock.txt.
Command-line reference
Syntax
odt-env [INI] [OPTIONS]
If no arguments are specified, odt-env treats the current working directory as ROOT and, when ROOT/odoo-project.ini exists,
regenerates the workspace artifacts without syncing repositories or recreating the virtual environment.
Project definition (INI)
INI is the optional project definition source used by odt-env. It can be:
-
a local filesystem path, for example:
odt-env /path/to/odoo-project.ini --sync-all --create-venv
-
a remote INI loaded from a Git repository, for example:
odt-env 'git+https://github.com/lck/odoo-devops-tools.git//examples/odoo-project.ini?ref=main' --sync-all --create-venv odt-env 'git+git@github.com:company/repo.git//examples/odoo-project.ini?ref=main' --sync-all --create-venv
Syntax:
git+REPO_URL//PATH/TO/PROJECT.ini?ref=REF
-
a remote INI loaded from a URL, for example:
odt-env 'https://github.com/lck/odoo-devops-tools/blob/main/examples/odoo-project.ini' --sync-all --create-venv odt-env 'https://raw.githubusercontent.com/lck/odoo-devops-tools/main/examples/odoo-project.ini' --sync-all --create-venv
Default project file convention
If no positional INI file is provided and no -i/--include option is used, odt-env looks for ROOT/odoo-project.ini.
This is similar to how Docker Compose uses compose.yaml by convention.
For example, this command:
odt-env --root ./existing-workspace --sync-all --create-venv
is equivalent to passing the default project file explicitly:
odt-env ./existing-workspace/odoo-project.ini --sync-all --create-venv
INI includes
Use -i INI / --include INI to include additional project layers. The option can be repeated.
odt-env base-odoo-project.ini -i local-overrides.ini -i extra-addons.ini --sync-all --create-venv
Project layers are processed from left to right. Later layers override earlier layers.
Validation is performed only after all layers have been merged.
The merged project file is saved as ROOT/odoo-project.ini, replacing any existing file at that path.
Paths and outputs
--root ROOT— workspace root directory. Default: the directory containing a local INI file, or the current working directory for a remote INI or omitted INI. In include mode, the default is the directory of the first local source, or the current working directory when the first source is remote.--init-project [ROOT]— createROOT/odoo-project.inifrom the bundled default template if it does not already exist.ROOTis optional; when supplied, it is a shorthand for selecting the workspace root directly, for exampleodt-env --init-project ./odoo19. When the optional value is omitted,--root ROOTremains supported for backward compatibility. Do not supply both--init-project ROOTand--root ROOT; the command exits with an error instead of choosing one implicitly. This option is valid only whenINIis omitted and no-i/--includeis provided. Existing project files are not overwritten.--include INI,-i INI— include an additional project INI layer; can be repeated. Later layers override earlier layers.--extra-var KEY=VALUE,-e KEY=VALUE— override or inject a value in the optional[vars]section; can be repeated.--set SECTION:KEY=VALUE,-S SECTION:KEY=VALUE— override a value that is already present in the INI file; can be repeated. New options are allowed only in the[config]section.--no-configs— do not generate config files.--no-scripts— do not generate helper scripts underROOT/odoo-scripts/.--no-data-dir— do not create the Odoo data directory.--no-provisioning-log— do not write provisioning metadata underROOT/.odt-env/.--show-last-run— print metadata fromROOT/.odt-env/last-provisioning.jsonand exit without provisioning.
Repository sync
--sync-odoo— sync only the Git-managed Odoo source; when[odoo].pathis used, the local path is reused and Git sync is skipped.--sync-addons— sync onlyROOT/odoo-addons/*.--sync-all— sync both Odoo and addons.
Note If any target repository contains local uncommitted changes,
odt-envaborts the sync operation. Commit, stash, or discard the changes before running a sync command.
Python, virtual environment, and wheelhouse
Online virtual environment provisioning:
--create-venv— recreateROOT/venvand refresh the wheelhouse; ifROOT/venvalready exists, it is deleted and created again.
Offline deployment from a prebuilt wheelhouse:
--create-venv-from-wheelhouse— recreateROOT/venvfrom an existingROOT/wheelhouse/andall-requirements.lock.txt, install strictly offline, and skip lock compilation and wheelhouse build. This is useful after preparing dependencies on an internet-connected build machine and copying the workspace to a target machine without internet access.
Maintenance:
--clear-pip-wheel-cache— remove all items from pip's wheel cache.
Portable workspace bundles
--create-bundle [BUNDLE]— create a verified portable ZIP containing Odoo sources, configured addon sources, a sanitizedodoo-project.ini, andROOT/wheelhouse/. IfBUNDLEis omitted, the output isROOT/dist/ROOT-NAME.odt.zip. Relative explicit output paths are resolved from the current working directory.--allow-dirty-bundle— allow--create-bundleto snapshot Git repositories with uncommitted changes. Without this option, dirty repositories abort bundle creation.--create-from-bundle BUNDLE— verify and extract a portable bundle into an emptyROOT, then recreateROOT/venvusing the bundled wheelhouse. This offline deployment path intentionally skips Docker workflow generation;--create-docker-deploycannot be combined with it.
Docker generation
- Docker workflow generation is enabled by default. It regenerates
ROOT/docker/local/andROOT/compose.yaml; addon sources are bind-mounted from the workspace into the Odoo container. Database and filestore backup/restore helpers, including optional restic filestore helpers, are generated underROOT/docker/local/scripts/. --no-local-docker— skip regeneration ofROOT/docker/local/andROOT/compose.yaml. Existing files are not deleted.--create-docker-deploy— generate a self-contained deployment build context underROOT/docker/deploy/. Addon modules are staged into the context.
Other options
--version— show the installedodt-envversion and exit.
Project file reference
The odt-env project file is an INI file that describes the Odoo workspace to create.
At minimum, the project file must contain this section:
[odoo]
The following sections are supported:
[vars]— optional reusable variables for INI interpolation[virtualenv]— optional Python and dependency settings[odoo]— required Odoo source settings[addons.<name>]— optional addon sources[docker]— optional Docker workflow/deploy generation settings[config]— optional Odoo server configuration values
General rules
- The project file can have any filename when passed explicitly. When
INIis omitted,odt-envuses the existingROOT/odoo-project.ini; if it is missing, use--init-projectto create it explicitly from the bundled default template. Remote INI sources and merged include layers are materialized asROOT/odoo-project.ini. - INI interpolation is supported, so values such as
${odoo:version}can be reused across sections. - Multiple INI layers can be composed with
-i/--include. Later layers override earlier layers; multi-line values are replaced as whole option values, not appended. - The optional
[vars]section is useful for reusable values referenced as${vars:name}. - Values from
[vars]can be overridden or injected from the CLI with-e name=value/--extra-var name=value. - Values that already exist in the INI file can be overridden directly with
-S section:key=value/--set section:key=value. - Multi-line values are used for lists such as
requirements,build_constraints, andrequirements_ignore.
[vars]
This section is optional.
Use it for reusable values that you want to interpolate in other sections.
A major advantage of [vars] is that its values can also be overridden directly from the CLI with -e KEY=VALUE / --extra-var KEY=VALUE. This makes it easy to keep a single project file and adjust things like Odoo version, branch, commit, or database name per run without editing the file.
Example:
[vars]
branch = 18.0
db = odoo
[odoo]
version = 18.0
branch = ${vars:branch}
[config]
db_name = ${vars:db}
db_user = odoo
db_password = odoo
CLI override example:
odt-env odoo-project.ini --sync-all --create-venv -e branch=dev -e db=odoo_dev
[virtualenv]
This section is optional.
python_version— Python version for the virtual environment. If omitted,odt-envchooses a default version based on the selected Odoo version.managed_python— whetheruvshould install and manage Python automatically. Default:true.requirements— additional Python requirements to install. Multi-line list.build_constraints— additional build constraints used during dependency compilation. Multi-line list.requirements_ignore— package names to ignore when collecting requirements from addon repositories. Multi-line list.
Example:
[virtualenv]
managed_python = false
python_version = 3.11
requirements =
lxml>=6
psycopg2-binary==2.9.9
requirements_ignore =
psycopg2
[odoo]
This section is required.
version— Odoo version inX.0format, for example18.0. Required.path— local Odoo source directory. Relative paths are resolved relative toROOT/.repo— Git repository URL for Odoo. Default: the official Odoo repository.branch— Git branch to check out. Default: the same value asversion.commit— optional Git commit to check out after fetching the selected branch. When set, the repository is pinned to that exact revision.shallow— whether to use a shallow clone. Default:true. Ignored whencommitis set.
Odoo must use exactly one of these source modes:
- local Odoo source:
version+path - Git-managed Odoo source:
version+ optionalrepo,branch,commit, andshallow
Git-managed example:
[odoo]
version = 18.0
repo = https://github.com/odoo/odoo.git
branch = 18.0
commit = e6ec487
shallow = true
Local source example:
[odoo]
version = 18.0
path = ../odoo
[addons.<name>]
Addon sections are optional. You can define as many as needed.
Each addon must use exactly one of these source types:
- local addon path:
path - Git repository:
repo+branch(+ optionalcommitandshallow)
Rules:
- For a local addon, use only
path. - For a Git addon,
repoandbranchare required. commitis optional for a Git addon. When set, the repository is pinned to that exact revision.shallowis optional for Git addons and defaults totrue. It is ignored whencommitis set.- Relative local paths are resolved relative to
ROOT/. - Git-based addons are cloned into
ROOT/odoo-addons/<name>/. - All configured addon directories are automatically appended to the generated
addons_path.
Examples:
[addons.my-custom-addons]
path = odoo-addons/my-custom-addons
[addons.oca-web]
repo = https://github.com/OCA/web.git
branch = ${odoo:version}
commit = abcdef1
[docker]
This section is optional.
base_image— Docker image used as the base image in both generated Dockerfiles. Default:odoo:${odoo:version}.
[config]
This section is optional.
When present, it contains Odoo server configuration values written into ROOT/odoo-configs/odoo-server.conf.
When omitted, odt-env still generates a valid config file with generated values such as addons_path and data_dir.
You can define standard Odoo configuration options here.
Special rules:
addons_pathmust not be set in[config].odt-envalways generates it automatically.data_dirmay be set in[config]. If provided, it overrides the default data directory location.
Example:
[config]
db_host = 127.0.0.1
db_port = 5432
db_name = odoo
db_user = odoo
db_password = odoo
http_port = 8069
Release files for odoo-devops-tools 1.20.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| odoo_devops_tools-1.20.3.tar.gz | 76.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| odoo_devops_tools-1.20.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 135.2 kB
Release files / odoo_devops_tools-1.20.3.tar.gz
| Download URL | odoo_devops_tools-1.20.3.tar.gz |
|---|---|
| Size | 76.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
adefcd58638a2d99decb16d5144df77561a022cae00aba53b799d1d9ec0ec3ff
|
|
BLAKE2b-256 checksum How to use checksums |
312ea511cb5d75952b317aafda602487e0cc6eaa5961d03f2fc57f7bfa90542a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / odoo_devops_tools-1.20.3-py3-none-any.whl
| Download URL | odoo_devops_tools-1.20.3-py3-none-any.whl |
|---|---|
| Size | 58.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
381f3f2001824fcd30e08319a47807ae107d99ea2716df6fa8779bde9a504e87
|
|
BLAKE2b-256 checksum How to use checksums |
19fcba1e89112c2968db44e90dcccb4b806d6773cd56432c7e6942730bc482e8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|