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 can be installed without rebuilding the image.
- 📂 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 report.
- 🏥 Image has a built-in health check.
Source: https://github.com/Mint-System/Odoo-Build/tree/main/images/odoo/
Usage
The Mint System Odoo image runs with a very basic configuration, but can also be highly customized with environment variables.
Minimal
The following compose.yml is a minimal setup:
services:
odoo:
container_name: odoo
image: mintsystem/odoo:18.0.20250725
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.20250725
depends_on:
db:
condition: service_healthy
environment:
PGHOST: db
PGUSER: odoo
PGPASSWORD: odoo
PGPORT: 5432
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_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#16.0,git@github.com:OCA/server-tools.git#16.0"
ODOO_ADDONS_PATH: /mnt/addons/,/mnt/enterprise/,/mnt/oca/,/mnt/themes/
ODOO_DATABASE: "16.0"
ODOO_INIT_DEMO_DATA: True
ODOO_INIT_LOGIN: odoo
ODOO_INIT_PASSWORD: *****
ODOO_INIT_LANG: de_CH
ODOO_INIT_ADDONS: server_environment_ir_config_parameter
ENVIRONMENT: production
PYTHON_INSTALL: prometheus-client
SERVER_WIDE_MODULES: session_db,module_change_auto_install
SESSION_DB_URI: postgres://odoo:odoo@db/16.0
PROXY_MODE: True
LOG_LEVEL: debug
MAX_CRON_THREADS: 4
LIST_DB: False
ADMIN_PASSWD: *****
DBFILTER: ^%d$
WORKERS: 4
LIMIT_REQUEST: 16384
LIMIT_TIME_CPU: 300
LIMIT_TIME_REAL: 600
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
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-archive
Run the clone-git-addons script to clone module repos:
docker compose exec odoo clone-git-addons
Run the init-db script to initalize the Odoo database:
docker compose exec odoo init-db
The scripts are configured with environment variables.
Start
Once you start the container the entrypoint.sh script will:
- Run the
set-addons-pathscript to assemble the addons path. - Run the
template-odoo-rcscript to template theodoo.conffile. - Run the
install-python-packagesscript to install the Python packages 😉. - Wait for the database to be ready.
- Run the
update-modulesscript if enabled. - Start the Odoo server.
Execute
Once the container is running, install modules with:
docker compose exec odoo init-module partner_firstname
Or update specific modules with this command:
docker compose exec odoo update-module partner_firstname
There is also the possiblity to update all modules:
docker compose exec odoo update-modules
For 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-translations
Not 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-tests
Once this command is finished, run the module tests.
docker exec odoo run-tests
Environment 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.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_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#16.0,git@github.com:Mint-System/Odoo-Apps-Server-Tools.gi#16.0
ADDON_GIT_REPO=https://github.com/OCA/server-tools.git#16.0,https://github.com/Mint-System/Odoo-Apps-Server-Tools.gi#16.0
If 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.
Initialize
Set these environment variables for the database init:
ODOO_DATABASEName of the Odoo database. No default is set.ODOO_INIT_DEMO_DATAIf enabled Odoo inits the database with demo data. Default isfalse.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.
Server Environment
The Odoo server can be configured using these env vars:
ENVIRONMENTProvide an environment name. Can be accessed withconfig.get("environment").PYTHON_INSTALLComma 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 isFalse.LOG_LEVELSet the logging level. Default isinfo.
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.
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.
Both options require ODOO_DATABASE and ODOO_ADDONS_PATH.
Test
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.
Build
This image can be customized by any extend.
Install packages
Update the image with Python packages.
FROM mintsystem/odoo:18.0.20250725
RUN uv pip install prometheus-client astor fastapi python-multipart ujson a2wsgi parse-accept-language pyjwt
Or with apt packages.
FROM mintsystem/odoo:18.0.20250725
RUN apt-get update && apt-get install -y libgl1-mesa-glx poppler-utils tesseract-ocr
Add custom Odoo conf
Copy custom Odoo conf file to the image.
FROM mintsystem/odoo:18.0.20250725
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 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/enterpriseOdoo Enterprise modules are downloaded to this folder./opt/odoo-venvThis is where Python packages are installed./var/lib/odooOdoo data folder./var/lib/odoo/filestoreFor every database name Odoo creates a filestore./var/lib/odoo/sessionsLocation where werkzeug stores session information./var/lib/odoo/gitThe cloned module repos are stored here.
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 memray
Finish 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/