Lightweight Docker Compose resources for Odoo development, staging, and
production-oriented environments. This repository can be used standalone, or
copied into an Odoo environment managed with @wpmoo/toolkit.
WPMoo Compose for Odoo is an independent project and is not affiliated with, endorsed by, or sponsored by Odoo S.A. Odoo is a trademark of Odoo S.A.
Compact generated-environment payload is the canonical layout (preferred by @wpmoo/toolkit):
resources/generated-env/compose.yaml
resources/generated-env/compose/dev.yaml
resources/generated-env/compose/stage.yaml
resources/generated-env/compose/prod.yaml
resources/generated-env/config/odoo/odoo.conf
resources/generated-env/resources/odoo/entrypoint.sh
Legacy standalone compatibility files (repository root):
docker-compose_17.0.yml
docker-compose_18.0.yml
docker-compose_19.0.yml
@wpmoo/toolkit resolves generated environments from resources/generated-env/ first.
The root-level files are retained for standalone compatibility with older scripts and
repositories that still refer to these filenames.
Default local settings use Odoo 19 on port 10019. Image tags can be
overridden in .env with ODOO_IMAGE and POSTGRES_IMAGE.
Standalone custom addons can be placed directly under:
addons/
WPMoo source repos are expected under:
odoo/custom/src/private/
At container startup, entrypoint.sh scans WPMoo source repositories for addon
folders containing __manifest__.py and creates symlinks in /mnt/wpmoo-addons.
The static Odoo config uses:
/usr/lib/python3/dist-packages/odoo/addons,/mnt/extra-addons,/mnt/wpmoo-addons
mkdir -p ../my_product_dev
cp -R resources/generated-env/. ../my_product_dev/
cp .env.example ../my_product_dev/.env
cd ../my_product_dev
./scripts/up.shSet WPMOO_ENV=stage or WPMOO_ENV=prod only after providing production-grade
secrets, storage volumes, and reverse proxy/TLS controls.
cp .env.example .env
./scripts/up.sh
./scripts/logs.shOpen:
http://localhost:10019
Run an Odoo shell/container command:
./scripts/shell.sh
./scripts/odoo-bin.sh --help
./scripts/psql.sh develRun a module lifecycle or test cycle:
./scripts/resetdb.sh devel base
./scripts/install.sh my_module devel
./scripts/update.sh my_module devel
./scripts/test.sh my_module
./scripts/test.sh my_module --db devel --mode update --tags /my_module
./scripts/uninstall.sh my_module develRun local quality checks for addons:
./scripts/check-addons.sh
./scripts/lint.shcheck-addons.sh validates discovered __manifest__.py files under addons/
and odoo/custom/src/private/ against the configured ODOO_VERSION. It also
rejects public addons under addons/ that depend on private addons under
odoo/custom/src/private/.
lint.sh takes no arguments. When a .pre-commit-config.yaml file is present,
it first runs pre-commit run -a, then runs the addon manifest checks. If
pre-commit is not installed, install it or remove the config file before
running lint.sh.
Create and restore a local development snapshot:
./scripts/snapshot.sh devel before-large-change
./scripts/restore-snapshot.sh --dry-run before-large-change devel
./scripts/restore-snapshot.sh before-large-change develsnapshot.sh [db] [snapshot-name] defaults to database devel and a timestamped
name. Each snapshot writes backups/snapshots/<name>.dump,
<name>.filestore.tar.gz, and <name>.json. The filestore archive contains the
matching Odoo filestore from data/filestore/<db> when it exists.
Set WPMOO_SNAPSHOT_RETENTION_COUNT to a positive integer to keep only the
newest snapshot manifests and their matching dump/filestore files.
restore-snapshot.sh [--dry-run] <snapshot-name> [db] validates and previews
the selected snapshot with --dry-run, or restores the dump and filestore into
the target database without it, replacing the current local database and
filestore for that database. Snapshot names may contain only letters, numbers,
dots, underscores, and dashes, and may not start with a dash.
Destructive database actions are guarded in WPMOO_ENV=stage and
WPMOO_ENV=prod. To intentionally run resetdb.sh or a real
restore-snapshot.sh in those environments, set:
WPMOO_ALLOW_DESTRUCTIVE=1Export a translation template with stock Odoo:
./scripts/pot.sh my_module devel i18n/my_module.potpot.sh <module[,module]> [db] [output] defaults to database devel and
i18n/<first-module>.pot. The module list can also come from ODOO_TEST_MODULE
in .env. The command uses stock odoo i18n export inside the Odoo container.
Stop:
./scripts/down.shRestart only Odoo:
./scripts/restart.shRoot legacy compose files are supported for older standalone workflows:
cp .env.example .env
docker compose -f docker-compose_19.0.yml up -d
docker compose -f docker-compose_18.0.yml up -d
docker compose -f docker-compose_17.0.yml up -dTraefik/reverse-proxy support is intentionally left out of the base template for now. It can be added later as an optional compose overlay/profile without making the local development path harder to understand.
- Keep local
.env,data/,postgresql/, and backups out of Git. - For production, set real secrets, non-default credentials, persistent volumes, and a reverse proxy with TLS before exposing services.
- For multi-version development, create a separate environment/worktree per Odoo branch.
If this project helps you, you can support the work here:

