Mint System Odoo
A better Odoo image.
This container image is an improvement of the official Odoo image:
- ðĶ Package management is handled with uv for Python and pnpm for Node.
- ð The Odoo source is based on a specific revision.
- ð The image build process ensures reproducibility.
- âïļ Configuration of
odoo.confis managed through environment variables. - ðą Addons are cloned from git repositories.
- ð ïļ Python packages are installed at runtime.
- ð The system detects addons in nested module folders.
- ðū Session information can be stored in the database.
- ðĨïļ Environment name is retrieved from server configuration.
- ð Database initialization with selected modules.
- ð The image includes built-in manifestoo and click-odoo-contrib.
- ðŠī The container runs without requiring root privileges.
- âïļ Reduced image size through multi-stage build and file cleanup.
- ð Use the image to run module tests and create code coverage reports.
- ðĨ Image has a built-in health check.
Source: https://github.com/Mint-System/Odoo-Build/tree/main/images/odoo/
Changelog: https://odoo.build/images/odoo/CHANGELOG.html
Usage
The Mint System Odoo image runs with a very basic configuration, but can also be highly customized with environment variables.
Supported tags:
Minimal
The following compose.yml is a minimal setup:
services:
odoo:
container_name: odoo
image: mintsystem/odoo:18.0
depends_on:
- db
environment:
PGHOST: db
PGUSER: odoo
PGPASSWORD: odoo
ports:
- "127.0.0.1:8069:8069"
volumes:
- odoo-data:/var/lib/odoo
db:
container_name: db
image: postgres:14-alpine
environment:
POSTGRES_USER: odoo
POSTGRES_PASSWORD: odoo
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- db-data:/var/lib/postgresql/data/pgdata
volumes:
odoo-data:
db-data:Customized
This compose.yml shows all possible configurations:
services:
odoo:
container_name: odoo
image: mintsystem/odoo:18.0
depends_on:
db:
condition: service_healthy
environment:
PGHOST: db
PGUSER: odoo
PGPASSWORD: odoo
PGPORT: 5432
DB_NAME: odoo
DB_MAXCONN: 128
PGSSLMODE: verify-ca
PGSSLROOTCERT: /mnt/postgres-secret/ca.crt
SMTP_SERVER: mail.infomaniak.com
SMTP_PORT: 587
SMTP_SSL: True
SMTP_USER: odoo@yourcompany.com
SMTP_PASSWORD: *****
EMAIL_FROM: odoo@yourcompany.com
MAIL_BOUNCE_ALIAS: bounce
MAIL_CATCHALL_ALIAS: reply
MAIL_CATCHALL_DOMAIN: yourcompany.com
MAIL_DEFAULT_FROM: odoo
MAIL_ALIAS_DOMAIN: yourcompany.com
ODOO_MAIL_SMTP_HOST: mail.infomaniak.com
ODOO_MAIL_SMTP_PORT: 587
ODOO_MAIL_SMTP_ENCRYPTION: starttls
ODOO_MAIL_SMTP_FROM_FILTER: odoo@yourcompany.com
ODOO_MAIL_IMAP_HOST: mail.infomaniak.com
ODOO_MAIL_IMAP_PORT: 993
ODOO_MAIL_IMAP_SSL: True
ODOO_MAIL_USERNAME: odoo@yourcompany.com
ODOO_MAIL_PASSWORD: *****
GIT_AUTHOR_NAME: "Your Name"
GIT_AUTHOR_EMAIL: you@example.com
GIT_SSH_PUBLIC_KEY: "ssh-ed25519 BBBBC3NzaC1lZDI1NTE5BBBBIDR9Ibi0mATjCyx1EYg594oFkY0rghtgo+pnFHOvAcym Mint-System-Project-MCC@github.com"
GIT_SSH_PRIVATE_KEY: "LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLQpiM0JsYm5OemFDMXJaWGt0ZGpFQUFBQUFCRzV2Ym1VQUFBQUVibTl1WlFBQUFBQUFBQUFCQUFBQU13QUFBQXR6YzJndFpXClF5TlRVeE9RQUFBQ0EwZlNHNHRKZ0U0d3NzZFJHSU9mZUtCWkdOSzRJYllLUHFaeFJ6cndITXBnQUFBS2k1WkJhRnVXUVcKaFFBQUFBdHpjMmd0WldReU5UVXhPUUFBQUNBMGZTRzR0SmdFNHdzc2RSR0lPZmVLQlpTks0SWJZS1BxWnhSenJ3SE1wZwowQkFnTT0KLS0tLS1FTkQgT1BFTlNTSCBQUklWQVRFIEtFWS0tLS0tCg=="
GITHUB_USERNAME: bot-mintsys
GITHUB_PAT: *****
GITLAB_URL: https://gitlab.com
GITLAB_USERNAME: bot-mintsys
GITLAB_PAT: *****
FORGEJO_URL: https://codeberg.org
FORGEJO_USERNAME: bot-mintsys
FORGEJO_PAT: *****
ADDONS_GIT_REPOS: "git@github.com:Mint-System/Odoo-Apps-Server-Tools.git#18.0,git@github.com:OCA/server-tools.git#18.0"
ODOO_ADDONS_PATH: /mnt/addons/,/mnt/enterprise/,/mnt/oca/,/mnt/themes/
ODOO_DATABASE: "18.0"
ODOO_INIT_LOGIN: odoo
ODOO_INIT_PASSWORD: *****
ODOO_INIT_LANG: de_CH
ODOO_INIT_ADDONS: server_environment_ir_config_parameter
RUNNING_ENV: production
WITHOUT_DEMO: False
PYTHON_INSTALL: |
prometheus-client
pyjwt
SERVER_WIDE_MODULES: session_db,module_change_auto_install
SESSION_DB_URI: postgres://odoo:odoo@db/18.0
PROXY_MODE: False
LOG_LEVEL: debug
MAX_CRON_THREADS: 4
LIST_DB: True
LOG_DB: True
LOG_HANDLER: ':INFO'
LOGFILE: None
ADMIN_PASSWD: *****
DB_FILTER: ^%d$
WORKERS: 4
LIMIT_REQUEST: 16384
LIMIT_TIME_CPU: 300
LIMIT_TIME_REAL: 600
LIMIT_MEMORY_HARD: 2684354560
LIMIT_MEMORY_SOFT: 2147483648
LIMIT_MEMORY_HARD_GEVENT: 1048579
LIMIT_MEMORY_SOFT_GEVENT: 1048576
MODULE_AUTO_INSTALL_DISABLED: odoo_test_xmlrunner
AUTO_UPDATE_MODULES: True
TEST_ADDONS_DIR: /mnt/oca/partner-contact
TEST_INCLUDE: partner_firstname
TEST_EXCLUDE: partner_fax
AUTO_UPDATE_TRANSLATIONS: True
AUTO_UPDATE_MODULES_LIST: True
ADDITIONAL_ODOO_RC: "syslog = True"
IR_CONFIG_PARAMETER: "web.base.url = https://odoo.example.com"
ports:
- "127.0.0.1:8069:8069"
volumes:
- odoo-data:/var/lib/odoo
- ./addons:/mnt/addons
- ./oca:/mnt/oca
- ./enterprise:/mnt/enterprise
- ./themes:/mnt/themes
db:
container_name: db
image: postgres:14-alpine
environment:
POSTGRES_USER: odoo
POSTGRES_PASSWORD: odoo
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- db-data:/var/lib/postgresql/data/pgdata
healthcheck:
test: ["CMD-SHELL", "pg_isready -U odoo -d $ODOO_DATABASE"]
interval: 5s
timeout: 5s
retries: 5
volumes:
odoo-data:
db-data:The environment variables are explained in detail further down.
Lifecycle
The Mint System Odoo image has this container lifecycle in mind:
- Initialize: Clone addons and initialize the database.
- Start: The container starts and updates the execution environment.
- Execute: Actions performed while the container is running.
- Analyze: Analyse the current state of the container.
- Test: Test modules in the container.
Initialize
Before starting the container you can initalize the database with selected scripts.
Run the download-git-archive script to download the Odoo Enterprise modules:
docker compose exec odoo download-git-archiveRun the clone-git-addons script to clone module repos:
docker compose exec odoo clone-git-addonsRun the init-db script to initalize the Odoo database:
docker compose exec odoo init-dbThe scripts are configured with environment variables.
Start
Once you start the container the entrypoint.sh script will:
- Call the
aggregate-git-reposscript and clone modules. - Run the
template-odoo-rcscript to template theodoo.conffile. - While doing so assemble the addons path with
set-addons-path. - Run the
install-python-packagesscript to install the Python packages. - Wait for the database to be ready.
- Run the
update-modulesscript if enabled. - Run the
update-modules-listscript if enabled. - Run the
update-translationsscript if enabled. - Start the Odoo server.
Execute
Once the container is running, install modules with:
docker compose exec odoo init-module partner_firstnameOr update specific modules with this command:
docker compose exec odoo update-module partner_firstnameThere is also the possiblity to update all modules:
docker compose exec odoo update-modulesOr update the modules list (refresh the list of available modules from the addons path):
docker compose exec odoo update-modules-listFor each installed module Odoo computes and stores a checksum in the database. The update modules script compares the checksum and updates all modules that have changed.
Updating module translations is simple:
docker compose exec odoo update-translationsNote that existing translations will be overwritten.
Analyze
With the manifestoo cli you can query the module manifest files.
List all modules:
docker exec odoo bash -c "manifestoo --select-found list --separator=,"Test
The run-tests script runs module tests and produces a coverage.xml file.
But first the server environment must be prepared to run tests.
docker exec odoo setup-testsOnce this command is finished, run the module tests.
docker exec odoo run-testsEnvironment Variables
The container can be configured with environment variables. This section shows all the variables in detail:
Database Connection
Odoo supports the PostgreSQL database only.
PGHOSTName of the database container.PGUSERDatabase username.PGPASSWORDDatabase user password.PGPORTPostgres server port. Default is5432.DB_NAMEFixed database name. Default is ``.DB_MAXCONN: Maximum database connection. default is64.PGSSLMODE: SSL mode for postgres connection. Default isprefer.PGSSLROOTCERT: Path too ssl root cert. Required when usingverify-camode.
SMTP Server
This is the mail configuration of the Odoo server.
SMTP_SERVERAdress of the SMTP server.SMTP_PORTPort of the SMTP server.SMTP_SSLUse ssl encryption.SMTP_USERSMTP username.SMTP_PASSWORDSMTP user password.EMAIL_FROMMail adress of the sender.
System Parameters
Set mail parameters for the company.
MAIL_BOUNCE_ALIAS: Name of the bounce mail adress.MAIL_CATCHALL_ALIAS: Name of the reply-to mail adress.MAIL_CATCHALL_DOMAIN: Domain name of the reply-to mail address.MAIL_DEFAULT_FROM: From address for outgoing mails.MAIL_ALIAS_DOMAIN: Mail domain of the company.
Incoming and Outgoing Mail-Server
Setup mail configuration for the database.
ODOO_MAIL_SMTP_HOST: If set Odoo sends mails to this host.ODOO_MAIL_SMTP_PORT: SMTP port. Default is587.ODOO_MAIL_SMTP_ENCRYPTION: SMTP encryption type. Default isstarttls.ODOO_MAIL_SMTP_FROM_FILTER: Send mails from this address only. Default is"".ODOO_MAIL_IMAP_HOST: If set Odoo fetches mails from this host.ODOO_MAIL_IMAP_PORT: IMAP port. Default is993.ODOO_MAIL_IMAP_SSL: Enable IMAP SSL. Default isTrue.ODOO_MAIL_USERNAME: Username of the Odoo mailbox.ODOO_MAIL_PASSWORD: Password of the Odoo mailbox.
The configuration will be applied to the ODOO_DATABASE database.
Module Repos
The image can clone git repositories.
- `GIT_AUTHOR_NAME: Set user name global git config.
- `GIT_AUTHOR_EMAIL: Set user email global git config.
GIT_SSH_PUBLIC_KEY: Public key for SSH connection.GIT_SSH_PRIVATE_KEY: Base64 encoded private key for SSH connection:cat ~/.ssh/id_ed2551 | base64 -w0GITHUB_USERNAMEGitHub username for https git clone and archive download.GITHUB_PAT: GitHub access token for https git clone and archive download.GITLAB_URL: Url of GitLab instance. Default ishttps://gitlab.com.GITLAB_USERNAME: GitLab Username for https git clone.GITLAB_PAT: GitLab access token for https git clone and archive download.FORGEJO_URL: Url of Forgejo instance. Default ishttps://codeberg.org.FORGEJO_USERNAME: Forgejo Username for https git clone.FORGEJO_PAT: Forgejo access token for https git clone and archive download.ADDONS_GIT_REPOSComma seperated list of git clone urls appended with#and branch name.
You can use https and git urls for ADDONS_GIT_REPOS:
ADDON_GIT_REPO=git@github.com:OCA/server-tools.git#18.0,git@github.com:Mint-System/Odoo-Apps-Server-Tools.gi#18.0
ADDON_GIT_REPO=https://github.com/OCA/server-tools.git#18.0,https://github.com/Mint-System/Odoo-Apps-Server-Tools.gi#18.0If you use a git url make sure a valid SSH private/public key is defined.
Addons Path
The entrypoint script searches for module folders in the addons path and creates a new addons path.
ODOO_ADDONS_PATHComma seperated list of container paths pointing to addon folders. Default is:/mnt/extra-addonsDefault location for custom modules./var/lib/odoo/enterpriseReserved location for Odoo enterprise modules./var/lib/odoo/gitReserved location for git repos.$TEST_ADDONS_DIRVariable location for module testing./opt/odoo/addonsReserved location for Odoo community modules.
Initialize
Set these environment variables for the database init:
ODOO_DATABASEName of the Odoo database for initialisation.ODOO_INIT_LOGINUsername of the admin user. Default isadmin.ODOO_INIT_PASSWORDPassword of the admin user. Default isadmin.ODOO_INIT_LANGLanguage used for database init. Default isen_US.ODOO_INIT_ADDONSProvide comma separated list of modules for database init. Default isweb.WITHOUT_DEMOIf enabled Odoo inits the database with demo data. Default isTrue.
Server Environment
The Odoo server can be configured using these env vars:
RUNNING_ENVProvide an environment name. Can be accessed withconfig.get("environment").PYTHON_INSTALLComma or line-break seperated list of python packages.SERVER_WIDE_MODULESComma separated list of modules to load with server. The variable will be prefixed withbase,web.SESSION_DB_URIConnection string for storing session data in database.PROXY_MODEEnable server proxy mode. Default isTrue.LOG_LEVELSet the logging level. Default isinfo.LOG_DBWhen enabled the database log is shown in the Odoo log. Default isFalse.LOG_HANDLERDefine the log handler. Default is[':INFO'].LOGFILESet the logging level. Default isNone.
Database Manager
The Odoo database manager is disabled by default.
LIST_DBEnable the database manager. Default isFalse.ADMIN_PASSWDMaster password for database manager. Default isodoo.DB_FILTERSet filter for database name. Default is.*.
Process Limits
Odoo is executed as a multi-threaded Python process.
MAX_CRON_THREADSMaximum count of cron threads. Default is2.WORKERSDefine how many workers should be spawned. Default is0.LIMIT_REQUESTMaximum number of requests per worker. Default is65536.LIMIT_TIME_CPUMaximum cpu time per request. Default is60.LIMIT_TIME_REALMaximum real time per request. Default is120.LIMIT_MEMORY_HARDHard memory limit for the Odoo process. Default is2560 * 1024 * 1024.LIMIT_MEMORY_SOFTSoft memory limit for the Odoo process. Default is2048 * 1024 * 1024.LIMIT_MEMORY_HARD_GEVENTSet hard memory limit for the gevent process. Default isFalse.LIMIT_MEMORY_SOFT_GEVENTSet soft memory limit for the gevent process. Default isFalse.
To calculate the amount of workers multply the amount of cpu cores by 2. To get the cpu core count run nproc.
Module Auto Install
With the module_change_auto_install module you can disable the auto installation of specific modules.
MODULE_AUTO_INSTALL_DISABLEDComma separated list of modules that should be auto installed. Requiresmodule_change_auto_installinSERVER_WIDE_MODULES.
Module Auto Update
The container uses click-odoo-contrib to update Odoo modules. The auto update is disabled by default.
AUTO_UPDATE_MODULESIf enabled modules will updated when the container is started. Default isFalse.AUTO_UPDATE_TRANSLATIONSIf enabled translatiosn will be updated when the container starts. Default isFalse.AUTO_UPDATE_MODULES_LISTIf enabled, the modules list will be updated when the container starts. Default isFalse.
Both options require ODOO_DATABASE and ODOO_ADDONS_PATH.
Testing
With this image you can also run module tests.
TEST_ADDONS_DIR: Provide the directory with the modules that should be tests.TEST_INCLUDEComma separated list of modules that should be test exlusively.TEST_EXCLUDE: Comma separated list of modules that should not be tested.
Additional Config
If you have additional config for Odoo use the vars:
ADDITIONAL_ODOO_RC: Added to the options section of the odoo.conf.IR_CONFIG_PARAMETER: Added to their.config_parametersection of the odoo.conf.
Naming
This image tries to stay compatible with other images such as https://github.com/acsone/odoo-bedrock or https://github.com/Tecnativa/doodba.
Compatibility with other images is mainly achieved by using the same environments variables and offering the same functionality.
Files
pyproject.toml
When mounting your pyproject.toml to /var/lib/odoo/pyproject.toml the sync-python-project script will run uv sync --active in the directory.
Here is an example for pyproject.toml:
# Use the hatchling build backend, with the hatch-odoo plugin.
[build-system]
requires = ["hatchling", "hatch-odoo"]
build-backend = "hatchling.build"
[project]
name = "MyAwesomeProject"
version = "1.0"
readme = "README.md"
requires-python = ">=3.8"
# Dependencies are dynamic because they will be generated from Odoo addons manifests.
dynamic = ["dependencies"]
# Enable the hatch-odoo metadata hook to generate dependencies from addons manifests.
[tool.hatch.metadata.hooks.odoo-addons-dependencies]
# Enable the hatch-odoo build hook to package the Odoo addons into odoo/addons.
[tool.hatch.build.hooks.odoo-addons-dirs]
[tool.hatch-odoo]
# If our addons have non standard version numbers, let's help hatch-odoo discover the Odoo version.
odoo_version_override = "18.0"
# Let's add additional dependencies that are not declared in addons manifests.
dependencies = ["click-odoo-contrib"]
# Our addons are in the project root directory.
addons_dirs = ["."]repos.yml
The image includes git-aggregator. It allows to clone and merge addon repos from different origins and branches.
When mounting the repos.yml to /var/lib/odoo/git/repos.yml the aggregate-git-repos script will run the gitaggregate command in the directory.
Here is an example for repos.yml:
github/oca/server-tools:
remotes:
oca: git@github.com:OCA/server-tools.git
merges:
- oca 18.0
target: oca 18.0Build
This image can be customized by any extend.
Install packages
Update the image with Python packages:
FROM mintsystem/odoo:18.0
RUN uv pip install prometheus-client astor fastapi python-multipart ujson a2wsgi parse-accept-language pyjwtOr with apt packages:
FROM mintsystem/odoo:18.0
RUN apt-get update && apt-get install -y libgl1-mesa-glx poppler-utils tesseract-ocrAdd custom Odoo conf
Copy custom Odoo conf file to the image.
FROM mintsystem/odoo:18.0
COPY ./odoo.conf.template /etc/odoo/Develop
See Odoo Build > Build and publish container image for details.
Internal paths
The most important image paths are:
/etc/odooContains theodoo.confandodoo.conf.templatefiles./mnt/extra-addonsNested module are loaded from this path by default./mnt/test-addonsRecommended mount path for modules to test./opt/odoo/addonsContains the Odoo community edition modules./opt/odoo-venvThis is where Python packages are installed./var/lib/odooOdoo data folder./var/lib/odoo/enterpriseOdoo enterprise modules are downloaded to this folder./var/lib/odoo/filestoreFor every database name Odoo creates a filestore./var/lib/odoo/gitThe cloned module repos are stored here./var/lib/odoo/sessionsLocation where werkzeug stores session information.
Capture memory profile
With memray you can visualize the memory usage of Odoo.
Run Odoo with memray.
docker compose exec -p 127.0.0.1:8069:8069 odoo memrayFinish the recording with ctrl+c.
Generate the flamegraph and copy the flamegraph to the host.
docker compose exec odoo python3 -m memray flamegraph /var/lib/odoo/memray-capture.bin
docker cp odoo:/var/lib/odoo/memray-flamegraph-capture.html ./tmp/Scripts
Under the hood the image uses several scripts to manage Odoo. Make yourself familiar with these scripts:
add-ssh-keyaggregate-git-reposcheck-database-initializedclone-git-addonsdownload-git-archiveinit-dbinit-moduleinstall-python-packageslog-entrypointparse-urlremove-ssh-keyrun-testsset-addons-pathsetup-mailsetup-testssync-python-projecttemplate-odoo-rcupdate-moduleupdate-modulesupdate-modules-listupdate-translationswait-for-pg