From a493867be01834c5c6bdaa491c9d26673582fcdc Mon Sep 17 00:00:00 2001 From: Eric Antones Date: Wed, 8 Apr 2026 18:43:20 +0200 Subject: [PATCH 1/7] [MIG] Dockerfile: migrate base from Debian stretch to bookworm Stretch has been EOL since 2022. Bookworm is the current Debian stable, and is what Odoo 19 officially targets (along with Noble). Changes: - FROM debian:stretch-slim -> debian:bookworm-slim - Remove stretch EOL workarounds (archive.debian.org sed, pgdg stretch) - Remove apt-transport-https (included in modern apt) PostgreSQL client is still installed from the official pgdg repo but pointing to bookworm-pgdg instead of stretch-pgdg (archive). --- Dockerfile | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index a3046f0..c532c56 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:stretch-slim +FROM debian:bookworm-slim ENV DEBIAN_FRONTEND=noninteractive @@ -6,15 +6,8 @@ ENV LANG=C.UTF-8 ENV LC_ALL=C.UTF-8 ENV LANGUAGE=C.UTF-8 -# Stretch is EOL -> use archive.debian.org -RUN sed -i 's|deb.debian.org/debian|archive.debian.org/debian|g' /etc/apt/sources.list && \ - sed -i 's|security.debian.org/debian-security|archive.debian.org/debian-security|g' /etc/apt/sources.list && \ - sed -i '/stretch-updates/d' /etc/apt/sources.list - -#RUN printf 'Acquire::Check-Valid-Until "false";\nAcquire::AllowInsecureRepositories "true";\n' > /etc/apt/apt.conf.d/99no-check-valid-until - RUN apt-get update && apt-get install -y --no-install-recommends \ - apt-transport-https vim ca-certificates curl git unzip rsync \ + vim ca-certificates curl git unzip rsync \ gcc build-essential \ python2.7 python-pip python-setuptools \ python-dev \ @@ -25,11 +18,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libpq-dev \ && apt-get clean && rm -rf /var/lib/apt/lists/* -# PostgreSQL client from official archive repo (Stretch EOL) +# PostgreSQL client from the official pgdg repo RUN install -d /usr/share/postgresql-common/pgdg && \ curl -fsSL -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \ https://www.postgresql.org/media/keys/ACCC4CF8.asc && \ - echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt-archive.postgresql.org/pub/repos/apt stretch-pgdg main" \ + echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" \ > /etc/apt/sources.list.d/pgdg.list && \ apt-get update && apt-get install -y --no-install-recommends postgresql-client && \ apt-get clean && rm -rf /var/lib/apt/lists/* From fd247eb0d51321fbefaa1193932fc36211854727 Mon Sep 17 00:00:00 2001 From: Eric Antones Date: Wed, 8 Apr 2026 18:45:21 +0200 Subject: [PATCH 2/7] [MIG] Dockerfile: install Odoo 19 system dependencies from apt Odoo 19 is a Python 3 only codebase. Replace Python 2.7 with Python 3 and install all Odoo 19 runtime dependencies as native Debian packages instead of pulling them through pip. The list of python3-* packages mirrors the Depends/Recommends of odoo/odoo's debian/control at the 19.0 tag. Installing from apt gives us: - Consistent versions against the Bookworm Python 3.11 interpreter - Pre-compiled C extensions (no toolchain needed at runtime) - Security updates through unattended-upgrades Also installed: the fonts Odoo ships with for web assets and PDF rendering (fonts-dejavu-core, fonts-inconsolata, fonts-font-awesome, fonts-roboto-unhinted), and libjs-underscore for the web client. The build toolchain (gcc, *-dev) is kept for any pip package that still needs to compile at bootstrap time via fetchreqs. --- Dockerfile | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index c532c56..7dae11a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,13 +9,62 @@ ENV LANGUAGE=C.UTF-8 RUN apt-get update && apt-get install -y --no-install-recommends \ vim ca-certificates curl git unzip rsync \ gcc build-essential \ - python2.7 python-pip python-setuptools \ - python-dev \ + python3 python3-pip python3-setuptools python3-venv \ + python3-dev \ libxml2-dev libxslt1-dev \ libldap2-dev libsasl2-dev \ libssl-dev \ libjpeg-dev zlib1g-dev \ libpq-dev \ + # Odoo 19 runtime dependencies (mirrors debian/control Depends) + python3-asn1crypto \ + python3-babel \ + python3-cbor2 \ + python3-chardet \ + python3-cryptography \ + python3-dateutil \ + python3-docutils \ + python3-freezegun \ + python3-geoip2 \ + python3-gevent \ + python3-greenlet \ + python3-idna \ + python3-jinja2 \ + python3-ldap \ + python3-libsass \ + python3-lxml \ + python3-magic \ + python3-markupsafe \ + python3-num2words \ + python3-ofxparse \ + python3-openpyxl \ + python3-openssl \ + python3-passlib \ + python3-pil \ + python3-polib \ + python3-psutil \ + python3-psycopg2 \ + python3-pypdf2 \ + python3-qrcode \ + python3-renderpm \ + python3-reportlab \ + python3-requests \ + python3-rjsmin \ + python3-stdnum \ + python3-tz \ + python3-urllib3 \ + python3-vobject \ + python3-werkzeug \ + python3-xlrd \ + python3-xlsxwriter \ + python3-zeep \ + # Fonts and web assets shipped with Odoo + fonts-dejavu-core \ + fonts-font-awesome \ + fonts-freefont-ttf \ + fonts-inconsolata \ + fonts-roboto-unhinted \ + libjs-underscore \ && apt-get clean && rm -rf /var/lib/apt/lists/* # PostgreSQL client from the official pgdg repo From 5f752394153d2f1749af7109101e12d293a3fd07 Mon Sep 17 00:00:00 2001 From: Eric Antones Date: Wed, 8 Apr 2026 18:50:15 +0200 Subject: [PATCH 3/7] [MIG] Dockerfile: create virtualenv at /opt/odoo/venv (PEP 668) Since Debian 12 (PEP 668), pip can no longer install into the system Python; it errors out with "externally-managed-environment". The 10.0 image relied on pip install --user which is now blocked. Create a dedicated virtualenv at /opt/odoo/venv with --system-site-packages so it can reuse the python3-* packages already installed from apt (lxml, psycopg2, reportlab, gevent...) while still letting pip install additional tooling such as git-aggregator, click-odoo-contrib and openupgradelib on top. The venv is owned by the odoo user so that fetchbasereqs/fetchreqs can run as odoo without needing root. /opt/odoo/venv/bin is prepended to PATH so "python" and "pip" resolve to the venv binaries. --- Dockerfile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 7dae11a..4d1aaf7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -109,7 +109,13 @@ RUN npm install -g less@2.7.3 less-plugin-clean-css@1.5.1 ENV HOME=/opt/odoo RUN useradd -m -u 99910 -d "$HOME" odoo -ENV PATH=$HOME/scripts/bin:$HOME/.local/bin:$PATH +# Virtualenv for pip-installed tooling (git-aggregator, click-odoo-contrib, +# openupgradelib). --system-site-packages lets the venv reuse python3-* +# packages installed from apt (lxml, psycopg2, reportlab, gevent, ...). +RUN python3 -m venv --system-site-packages /opt/odoo/venv && \ + chown -R odoo:odoo /opt/odoo/venv + +ENV PATH=/opt/odoo/venv/bin:$HOME/scripts/bin:$HOME/.local/bin:$PATH # image defaults (baked in) COPY --chown=odoo:odoo config/ /opt/odoo/dist/ From 2b545168749027f4b7bfe821be7d404d3c1300e0 Mon Sep 17 00:00:00 2001 From: Eric Antones Date: Wed, 8 Apr 2026 18:50:53 +0200 Subject: [PATCH 4/7] [MIG] Dockerfile: remove Node.js and less (not needed in Odoo 14+) Odoo 10 used the less CSS preprocessor at runtime to compile web assets, which in turn required Node.js and the less npm package. Starting with Odoo 14 the web framework compiles SCSS natively via python3-libsass (already installed in the previous commit), so: - Node.js 6.x is no longer required at all - The less and less-plugin-clean-css npm packages are dropped Removing Node saves ~80 MB from the image and eliminates a dependency chain that has been stuck on a very old Node release (6.17.1) for years. --- Dockerfile | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4d1aaf7..2bebb9d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -92,19 +92,6 @@ RUN set -eux; \ ENV PYTHONIOENCODING=UTF-8 -# ---- Node.js 6.x (official binary) for Odoo 10 ---- -ENV NODE_VERSION=6.17.1 -RUN set -eux; \ - cd /tmp; \ - curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz" -o node.tar.xz; \ - tar -xJf node.tar.xz; \ - cp -r node-v${NODE_VERSION}-linux-x64/bin /usr/local/; \ - cp -r node-v${NODE_VERSION}-linux-x64/lib /usr/local/; \ - cp -r node-v${NODE_VERSION}-linux-x64/include /usr/local/; \ - cp -r node-v${NODE_VERSION}-linux-x64/share /usr/local/; \ - rm -rf /tmp/node* -RUN npm install -g less@2.7.3 less-plugin-clean-css@1.5.1 - # optional: create a fixed user ENV HOME=/opt/odoo RUN useradd -m -u 99910 -d "$HOME" odoo From d8441337f783835dfc9fc61c4ce6892b991355fc Mon Sep 17 00:00:00 2001 From: Eric Antones Date: Wed, 8 Apr 2026 18:58:46 +0200 Subject: [PATCH 5/7] [MIG] Dockerfile: upgrade wkhtmltopdf to 0.12.6.1-3 for bookworm Odoo's PDF rendering requires wkhtmltopdf built against the patched Qt fork; the plain apt package from Debian (without patched Qt) produces broken headers, footers and tables. Use the official .deb built for bookworm from the wkhtmltopdf/ packaging releases. This is the last 0.12.x release (upstream is deprecated but remains the reference build for Odoo). Also switch from "dpkg -i" to "apt-get install ./wkhtml.deb" so that any transitive dependency declared by the .deb is resolved automatically instead of failing at install time. --- Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2bebb9d..9c6f2df 100644 --- a/Dockerfile +++ b/Dockerfile @@ -76,7 +76,7 @@ RUN install -d /usr/share/postgresql-common/pgdg && \ apt-get update && apt-get install -y --no-install-recommends postgresql-client && \ apt-get clean && rm -rf /var/lib/apt/lists/* -## wkhtmltopdf +## wkhtmltopdf (patched-Qt build required by Odoo) RUN apt-get update && apt-get install -y --no-install-recommends \ fontconfig libfreetype6 libpng16-16 \ libx11-6 libxcb1 libxext6 libxrender1 \ @@ -85,10 +85,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ RUN set -eux; \ cd /tmp; \ curl -fsSL \ - https://github.com/wkhtmltopdf/packaging/releases/download/0.12.1.4-2/wkhtmltox_0.12.1.4-2.stretch_amd64.deb \ + https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_amd64.deb \ -o wkhtml.deb; \ - dpkg -i wkhtml.deb; \ - rm -f wkhtml.deb + apt-get update && apt-get install -y --no-install-recommends ./wkhtml.deb && \ + apt-get clean && rm -rf /var/lib/apt/lists/* wkhtml.deb ENV PYTHONIOENCODING=UTF-8 From c537fa1a4043fc9e72b18ef15939ea006b6a845b Mon Sep 17 00:00:00 2001 From: Eric Antones Date: Wed, 8 Apr 2026 19:00:07 +0200 Subject: [PATCH 6/7] [MIG] scripts: migrate to Python 3 Drop the Python 2 compatibility shims in the helper scripts: scripts/lib/common.sh pip_install() no longer passes --user. Under Debian 12+ (PEP 668), --user is blocked against the system Python, and we now run pip from /opt/odoo/venv instead (prepended to PATH in the Dockerfile), so packages are installed into the venv automatically. scripts/bin/genaddonspath.py Shebang changed from "#!/usr/bin/env python" to "#!/usr/bin/env python3". Removed the pipes.quote fallback; shlex.quote is available on all supported Python 3 versions. --- scripts/bin/genaddonspath.py | 8 ++------ scripts/lib/common.sh | 7 ++++--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/scripts/bin/genaddonspath.py b/scripts/bin/genaddonspath.py index 5268412..c3bc289 100644 --- a/scripts/bin/genaddonspath.py +++ b/scripts/bin/genaddonspath.py @@ -1,15 +1,11 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ Generate addons_path parameter for odoo.conf from repos.yaml and update odoo.conf """ import io import re import os -# shlex.quote is Python 3+; fall back to pipes.quote for Python 2 -try: - from shlex import quote -except ImportError: - from pipes import quote +from shlex import quote import subprocess import yaml diff --git a/scripts/lib/common.sh b/scripts/lib/common.sh index 2e7f622..af7bf1b 100644 --- a/scripts/lib/common.sh +++ b/scripts/lib/common.sh @@ -11,11 +11,12 @@ else exit 1 fi -# Install Python packages with common pip options +# Install Python packages with common pip options. +# Runs inside the /opt/odoo/venv virtualenv (first in PATH). # Usage: pip_install [pip args...] pip_install() { # shellcheck disable=SC2154 # DIST_CONSTRAINTS from defaults.env - pip install --upgrade --user --no-cache-dir \ + pip install --upgrade --no-cache-dir \ --constraint "${DIST_CONSTRAINTS}" \ "$@" } @@ -66,4 +67,4 @@ safe_remove_dir() { debug_pause() { echo "DEBUG: Paused at '${1:-}'. Container will stay alive. Attach with 'docker exec'." sleep infinity -} \ No newline at end of file +} From 165f1c9389c5c1b12dd5e862c8b19af2d3fbb020 Mon Sep 17 00:00:00 2001 From: Eric Antones Date: Wed, 8 Apr 2026 19:01:22 +0200 Subject: [PATCH 7/7] [MIG] config: update defaults for Odoo 19 config/defaults.env PYTHON_BIN now points to the venv interpreter (/opt/odoo/venv/bin/python). The venv sits first in PATH so bare "python" and "pip" resolve there too, but PYTHON_BIN is used explicitly by odoo_exec() to invoke odoo-bin. config/constraints.txt Reset to an empty (commented) file. The previous pins (python-stdnum<2.0, Unidecode<1.3, isodate<0.7, zeep<4) were Python 2 era constraints for Odoo 10 and no longer apply: Odoo 19 ships its own requirements.txt with much newer versions, and the base python3-* packages are already installed from apt. Instance-specific constraints can still be added to this file if an addon needs a particular version to be pinned. --- config/constraints.txt | 12 ++++++++---- config/defaults.env | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/config/constraints.txt b/config/constraints.txt index c6bfe13..57bdd78 100644 --- a/config/constraints.txt +++ b/config/constraints.txt @@ -1,4 +1,8 @@ -python-stdnum<2.0 -Unidecode<1.3 -isodate<0.7 -zeep<4 +# Pip constraints baked into the image. +# +# Odoo 19 ships its own requirements.txt with modern pins, and the +# base python3-* packages are installed from apt; there are no global +# constraints needed at image-build time. +# +# Add entries here only if a custom addon or OCA repo needs a specific +# version to be forced during bootstrap (fetchreqs / fetchbasereqs). diff --git a/config/defaults.env b/config/defaults.env index f71b7bf..061ac45 100644 --- a/config/defaults.env +++ b/config/defaults.env @@ -1,6 +1,6 @@ # Odoo Docker Image Configuration # Default values - can be overridden by instance settings.env (bind-mounted at runtime) -PYTHON_BIN=/usr/bin/python +PYTHON_BIN=/opt/odoo/venv/bin/python # Dist directory (baked into image) DIST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"