Odoo Env — Docker-based Odoo Environment Manager

Dockerized environment to ease odoo development

Odoo Env — Docker-based Odoo Environment Manager

Who is this for?

Odoo developers who want to install and manage Odoo instances quickly, consistently, and without knowing Docker internals. Also useful for anyone deploying multiple Odoo projects with different versions on the same machine.

What is Odoo Env?

Odoo-env is a CLI tool (oe) that manages Docker-based Odoo environments. It reads an Odoo module manifest to understand everything about a deployment — repositories, Docker images, configuration — so a single manifest completely defines a project.

Key Features

Quick Start

# Install
pipx install odoo-env

# Install a project from its repository
oe -i git@github.com:your-org/your-project.git -c yourclient

# Pull images and extract sources for debug
oe -p -i

# Start the environment
oe -R -r

# Update modules
oe -u

# Restore latest backup
oe --restore

Full Command Reference

Environment setup

Command Description
-i [URL] Install environment. If a URL is given, clones the repo and auto-discovers the project name from the manifest. Without URL, updates all repositories for the configured client.
-p Pull all Docker images declared in the client manifest. In debug mode, also extracts Odoo sources to the host.
-w Create / overwrite the odoo.conf file from manifest config.

Runtime

Command Description
-R Run environment containers: postgres, wdb (debug mode), aeroo (old Odoo versions).
-r Run Odoo container. Detached in prod, interactive in debug.
-S Stop environment containers.
-s Stop Odoo container.

Database

Command Description
-u Update modules. Use -m module for specific modules, or omit for all. Use -d database for non-default databases.
-I module Install a module into the client database (comma-separated for several). New modules are installed with -i; modules already installed are updated with -u instead of reinstalled. Use -d database for non-default databases.
--restore Restore a backup into the client database. By default restores the newest .zip in backup_dir. Use -f for a specific file, -d for a target database.
--no-deactivate Skip database deactivation before restore. Deprecated.
--create-test-db Create a [client]_test database: restores the test seed, then installs every module found in the repository.

Testing

Command Description
-Q sale,stock Run Odoo tests on comma-separated module list. Uses the [client]_test database with admin/admin credentials. Add -d database to override.

Configuration

Command Description
-c CLIENT Set the default client name. Persistent — saved in config.
-d DATABASE Set the default database name. Persistent.
--debug Set environment to debug mode. Persistent.
--prod Set environment to production mode. Persistent.
--base-dir PATH Set root directory for all environments (e.g. /odoo_ar/). Persistent. Does not require a client to be configured.
--deploy-keys (Prod mode only) Generate SSH deploy key pairs for every private repository in the manifest. Prints public keys for adding to GitHub/GitLab.

Utilities

Command Description
-H Show odoo --help from the Odoo image declared in the manifest.
-V Show odoo-env version and exit.
-v Verbose mode — prints every command before execution.

Directory Structure

/odoo_ar/                    # --base-dir (default)
└── odoo-18.0/               # version + optional 'e' for Enterprise
    └── clientname/
        ├── config/          # odoo.conf
        ├── data_dir/        # Odoo filestore
        ├── backup_dir/      # .zip backups for --restore
        ├── log/             # odoo.log
        ├── postgresql/      # PostgreSQL data volume
        └── sources/         # cloned git repositories
    ├── src/                 # Odoo core sources (debug, v11-v18)
    ├── site-packages/       # venv packages (debug, v19+)
    └── lib/                 # python libs (debug, v11-v18)

Supported Odoo Versions

Odoo Python Special notes
8 – 10 2.7 Uses dist-packages, extra-addons
11 – 12 3.5 – 3.7 Uses dist-packages
13 3.7  
14 – 16 3.9 Uses src + lib mounts
17 3.10 Uses src + lib mounts
18 3.12 Uses src + lib mounts
19 3.10 (venv) Uses odoo-bin, src + site-packages

Docker images are hosted at Docker Hub and Dockerfiles at GitHub.

Manifest Format (env-ver: 2)

The manifest is a standard Odoo __manifest__.py with extra keys that only odoo-env reads. Odoo itself ignores them, so the module remains installable.

Required keys:

Optional keys:

See the full manifest example below.


Author: Jorge Obiols jorge.obiols@gmail.com

GitHub repo · Report an issue

THE PROJECT, where all the install information resides

What you need to know:

  1. The project is an Odoo module.
  2. This module has an extended manifest. Odoo does not read the extended keywords, so the module remains installable.
  3. Odoo-env reads the manifest to know how to install the system.
  4. The manifest holds:

    • Odoo Version: derived from the standard version keyword (e.g. 18.0.1.0.0 → branch 18.0)
    • env-ver: manifest syntax version — must be '2'
    • config / config-local: parameters written to odoo.conf (prod vs debug)
    • odoo-license: 'CE' (Community, default) or 'EE' (Enterprise)
    • port / longpolling_port: HTTP and longpolling ports
    • git-repos: list of repositories to clone
    • docker-images: list of Docker images to pull
    • prod_server: SSH alias for production server (used by --restore workflows that involve SCP)

As a best practice, list all required modules in the depends key. Then the project not only installs the environment but also documents which modules are needed. Run oe -u to install them all in one shot — it runs odoo-bin --update all --stop-after-init inside the container.

Syntax and examples

git-repos

General syntax: <repo-url> [<target-dir>[/<subdir>]] [-b <branch>]

Odoo-env automatically determines the branch from the Odoo version in the manifest (e.g. version: '18.0.1.0.0' → branch 18.0). Override with -b when a repo doesn’t follow this convention.

Basic example:

'git-repos': [
    'https://github.com/OCA/account-invoicing.git',
    'https://github.com/OCA/account-financial-tools.git',
]

Tree:

sources/
├── account-invoicing/
└── account-financial-tools/

Renaming to avoid collisions:

'git-repos': [
    'https://github.com/OCA/account-invoicing.git oca-account-invoicing',
    'https://github.com/ingadhoc/account-invoicing.git adhoc-account-invoicing',
]

Tree:

sources/
├── oca-account-invoicing/
└── adhoc-account-invoicing/

Single-module repos (nesting):

'git-repos': [
    'https://github.com/ctmil/meli_oerp.git ctmil/meli_oerp',
]

Tree:

sources/
└── ctmil/
    └── meli_oerp/

Custom branch override:

'git-repos': [
    'https://github.com/ctmil/odoo_barcode.git ctmil/odoo_barcode -b main',
]

SSH protocol (uses your SSH keys):

'git-repos': [
    'git@github.com:jobiols/private-repo.git private-repo -b 18.0',
]

docker-images

Syntax: <short-name> <image:tag>

The short-name is how odoo-env refers to the image internally. odoo, postgres, aeroo, and nginx are recognized names.

'docker-images': [
    'odoo jobiols/odoo-jeo:18.0',
    'postgres postgres:17.5-alpine',
]

Full manifest example

{
    'name': 'myproject',
    'version': '18.0.1.0.0',
    'category': 'Tools',
    'summary': 'Example project for Odoo 18 CE',
    'author': 'jeo Software',
    'website': 'https://github.com/jobiols/odoo-env',
    'license': 'AGPL-3',
    'depends': [
        'sale_management',
        'account',
    ],
    'installable': True,
    'application': False,

    # ---------- odoo-env manifest (env-ver: 2) ----------

    'env-ver': '2',

    # Community or Enterprise
    'odoo-license': 'CE',

    # HTTP port
    'port': '8069',

    # Production server SSH alias (for backup transfer)
    'prod_server': 'ubuntu@my-server',

    # ---------- odoo.conf for production ----------
    'config': [
        'workers = 4',
        'max_cron_threads = 1',
        'limit_request = 8192',
        'limit_memory_soft = 2147483648',
        'limit_memory_hard = 2684354560',
        'limit_time_cpu = 60',
        'limit_time_real = 120',
        'admin_passwd = my-secure-password',
        'dbfilter = myproject',
        'db_maxconn = 64',
        'log_level = info',
        'logfile = /var/log/odoo/odoo.log',
    ],

    # ---------- odoo.conf for debug ----------
    'config-local': [
        'admin_passwd = admin',
        # In debug mode, workers/max_cron_threads/limit_time_* are
        # forced to 0 automatically by odoo-env.
    ],

    # ---------- Repositories ----------
    'git-repos': [
        'https://github.com/OCA/web.git oca-web',
        'https://github.com/OCA/server-tools.git oca-server-tools',
        'https://github.com/ingadhoc/odoo-argentina.git adhoc-odoo-argentina',
        'git@github.com:myorg/private-modules.git private-modules -b 18.0',
    ],

    # ---------- Docker images ----------
    'docker-images': [
        'odoo jobiols/odoo-jeo:18.0',
        'postgres postgres:17.5-alpine',
    ],

    # ---------- External system dependencies ----------
    'external_dependencies': {
        'python': ['requests', 'openpyxl'],
    },
}

Configuration file

Odoo-env stores its own configuration at ~/.config/oe/oe_config.yaml:

base_dir: /odoo_ar/
client: myproject
environment: debug
last_version_check: '2026-05-23'
clients:
  - myproject: /odoo_ar/odoo-18.0/myproject/sources/cl-myproject/myproject
  - otherproj: /odoo_ar/odoo-16.0e/otherproj/sources/cl-otherproj/otherproj

Docker Images Reference

Odoo Images

Pre-built Odoo images for all Community versions from 8.0 to 19.0 are hosted on Docker Hub.

The Dockerfiles to build these images (or create your own) are at github.com/jobiols/docker-odoo-jeo.

You are encouraged to fork the repo and customize images for your needs.

Version Compatibility Table

Odoo version Odoo image tag Postgres WDB image
8.0 jobiols/odoo-jeo:8.0 postgres:9.6-alpine kozea/wdb
9.0 jobiols/odoo-jeo:9.0 postgres:9.6-alpine kozea/wdb
10.0 jobiols/odoo-jeo:10.0 postgres:9.6-alpine kozea/wdb
11.0 jobiols/odoo-jeo:11.0 postgres:10.1-alpine kozea/wdb
12.0 jobiols/odoo-jeo:12.0 postgres:10.1-alpine kozea/wdb
13.0 jobiols/odoo-jeo:13.0 postgres:10.1-alpine kozea/wdb
14.0 jobiols/odoo-jeo:14.0 postgres:13-alpine kozea/wdb
15.0 jobiols/odoo-jeo:15.0 postgres:13-alpine kozea/wdb
16.0 jobiols/odoo-jeo:16.0 postgres:13-alpine jobiols/wdb:3.3.1
17.0 jobiols/odoo-jeo:17.0 postgres:17.5-alpine jobiols/wdb:3.3.2
18.0 jobiols/odoo-jeo:18.0 postgres:17.5-alpine jobiols/wdb:3.3.2
19.0 jobiols/odoo-jeo:19.0 postgres:17.5-alpine jobiols/wdb:3.3.2

Note: For Odoo 19+, the entrypoint changes from odoo.py to odoo-bin.

Other Images

Image Purpose Notes
aeroo Aeroo reports engine Only used for Odoo ≤ 9. Can be omitted for newer versions.
dbtools Database backup/restore tools jobiols/dbtools:1.3.1 — used internally by backup operations.

Postgres version notes

How images are declared

In the manifest docker-images list, each entry is a pair:

'short-name image:tag'

The short-name tells odoo-env which role the image plays. Recognized names: odoo, postgres, aeroo, nginx.

Example:

'docker-images': [
    'odoo jobiols/odoo-jeo:18.0',
    'postgres postgres:17.5-alpine',
]

In debug mode, odoo-env automatically pulls the debug variant of the Odoo image (if available) and extracts sources to the host. In production mode, it pulls the standard image.

THE MAGIC BEGINS — From a fresh VPS to a running Odoo system

This example uses Ubuntu Server 24.04 LTS. Adapt for your distribution.

1. Prepare the host

# Upgrade the system
sudo apt update && sudo apt upgrade -y

# Install pipx (recommended way to install odoo-env)
sudo apt install pipx -y
pipx ensurepath

# Install odoo-env
pipx install odoo-env

# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
rm get-docker.sh

# Add your user to the docker group (log out and back in afterwards)
sudo usermod -aG docker $USER

# Verify tools
oe -V
docker --version

2. Create a project

You need an Odoo module with an extended manifest. The simplest approach is to keep it in a git repository so you can install with a single command.

Minimal manifest (__manifest__.py):

{
    'name': 'myproject',
    'version': '18.0.1.0.0',
    'category': 'Tools',
    'summary': 'My Odoo 18 project',
    'author': 'jeo Software',
    'license': 'AGPL-3',
    'depends': [],
    'installable': True,
    'application': False,

    'env-ver': '2',

    'git-repos': [
        'https://github.com/OCA/web.git',
    ],

    'docker-images': [
        'odoo jobiols/odoo-jeo:18.0',
        'postgres postgres:17.5-alpine',
    ],
}

3. Install the project

You can install from a local repo or directly from a remote URL:

# Option A: Install from a remote repository (auto-discovers project name)
oe -i git@github.com:your-org/myproject.git -c myproject

# Option B: If you already have the repo cloned locally
cd /path/to/myproject
oe -i -c myproject

This creates the directory structure under --base-dir (default /odoo_ar/):

/odoo_ar/
└── odoo-18.0/
    └── myproject/
        ├── config/
        ├── data_dir/
        ├── backup_dir/
        ├── log/
        ├── postgresql/
        └── sources/
            └── web/

Note: After installation, the original cloned repo can be deleted — the working copy lives in sources/.

4. Pull images and extract sources (debug mode)

# Set debug mode
oe --debug

# Pull Docker images and extract Odoo sources to the host
oe -p -i

# Write the odoo.conf
oe -w

# Start the environment (postgres + wdb debugger) and Odoo
oe -R -r

Odoo starts in interactive mode with WDB attached. Open http://localhost:8069 in your browser and create a database. The default master password in debug mode is admin.

5. Production deployment

# Set production mode
oe --prod

# Install, pull images, start
oe -i -p -w
oe -R -r

In production, Odoo runs detached with optimized worker settings. Workers and cron threads are calculated automatically from CPU count unless overridden in the manifest.

6. Day-to-day commands

# Restart Odoo
oe -s -r

# Stop everything
oe -S

# Start everything again
oe -R -r

# Update all repositories
oe -i

# Pull latest Docker images
oe -p

# Update all modules in the database
oe -u

# Update a specific module
oe -u -m sale

# Restore the latest backup
oe --restore

# Restore a specific backup file
oe --restore -f backup_2025_01_15.zip

# Restore to a different database
oe --restore -d myproject_test

# Generate deploy keys for private repos (production only)
oe --prod --deploy-keys

# Switch between projects
oe -c otherproject

# Run tests
oe -Q sale,stock -d myproject_test

# Show Odoo help from the container
oe -H

# Verbose mode — see every command
oe -v -R

7. Upgrading odoo-env

Odoo-env automatically checks PyPI for newer versions once per day and warns you if an update is available.

pipx upgrade odoo-env

8. The configuration file

Everything that is persistent is stored in ~/.config/oe/oe_config.yaml. You generally don’t need to edit it by hand — odoo-env manages it automatically.

base_dir: /odoo_ar/
client: myproject
environment: debug
last_version_check: '2026-05-23'
clients:
  - myproject: /odoo_ar/odoo-18.0/myproject/sources/cl-myproject/myproject_default

To change the root directory on systems where /odoo_ar/ doesn’t work (e.g. macOS):

oe --base-dir /Users/you/odoo_ar/