Installing Odoo from Source: A Step-by-Step Guide

How to install Odoo step by step on Debian, Ubuntu, macOS and Windows (WSL). Complete guide from Python compilation to deployment with PostgreSQL and git-aggregator.

Infrastructure Crystallization generative art

1. Prerequisites by operating system

1.1 Linux — Debian / Ubuntu

Recommended versions:

  • Odoo <= 16.0: Debian 11 (Bullseye), Debian 12 (Bookworm), Ubuntu 20.04, Ubuntu 22.04
  • Odoo >= 17.0: Debian 12 (Bookworm), Debian 13 (Trixie), Ubuntu 22.04, Ubuntu 24.04
  • Odoo 19.0: Debian 13 (Trixie), Ubuntu 24.04 (recommended, as it ships Python 3.12)

Odoo.sh (Odoo's official platform) runs on Debian, so Debian is the reference distribution.

Debian 12 (Bookworm) — Python 3.11

sudo apt update && sudo apt upgrade -y
sudo apt install -y \
    git python3.11 python3.11-dev python3.11-venv python3-pip \
    libpq-dev libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev \
    libjpeg-dev zlib1g-dev libfreetype6-dev wkhtmltopdf build-essential wget

Debian 13 (Trixie) — Python 3.12

sudo apt update && sudo apt upgrade -y
sudo apt install -y \
    git python3.12 python3.12-dev python3.12-venv python3-pip \
    libpq-dev libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev \
    libjpeg-dev zlib1g-dev libfreetype6-dev wkhtmltopdf build-essential wget

Ubuntu 22.04 (Jammy) — Python 3.10

sudo apt update && sudo apt upgrade -y
sudo apt install -y \
    git python3.10 python3.10-dev python3.10-venv python3-pip \
    libpq-dev libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev \
    libjpeg-dev zlib1g-dev libfreetype6-dev wkhtmltopdf build-essential wget

Ubuntu 24.04 (Noble) — Python 3.12

sudo apt update && sudo apt upgrade -y
sudo apt install -y \
    git python3.12 python3.12-dev python3.12-venv python3-pip \
    libpq-dev libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev \
    libjpeg-dev zlib1g-dev libfreetype6-dev wkhtmltopdf build-essential wget

1.2 macOS

# Install Homebrew (if not already installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Install dependencies
brew install python@3.12 postgresql git libxml2 libxslt jpeg libpng freetype wkhtmltopdf
brew services start postgresql

1.3 Windows (WSL)

Recommended version: Ubuntu 24.04 LTS (Python 3.12 included). Ubuntu 22.04 LTS reaches end of support in less than a year, so Ubuntu 24.04 is the better choice for new installations.

1.3.1 Prepare Windows for WSL

Step 1: enable the Virtual Machine Platform (required for WSL2)

The "Virtual Machine Platform" feature must be enabled in Windows for WSL2 to work.

  • Open Control Panel > Programs > Turn Windows features on or off
  • Find and tick Virtual Machine Platform
  • Restart the machine

If it is not enabled, running wsl --install fails with:

WSL2 cannot start because virtualization is not enabled on this machine.
Error code: Wsl/InstallDistro/Service/RegisterDistro/CreateVm/HCS/HCS_E_HYPERV_NOT_INSTALLED

Step 2: enable virtualization in the BIOS (if applicable)

If the Virtual Machine Platform is already enabled but the error persists, virtualization has to be turned on in the machine's BIOS/UEFI:

  • Restart the machine and enter the BIOS (usually F2, F10 or Del)
  • Look for the CPU or Advanced section
  • Enable Intel VT-x (Intel) or AMD-V (AMD)
  • Save and reboot

Note: on virtual machines (Proxmox, VMware, VirtualBox), nested virtualization must be enabled in the VM settings.

Step 3: install WSL

Open PowerShell as administrator and run:

# Update WSL to the latest version
wsl --update

# Restart WSL
wsl --shutdown

# List the available distributions
wsl --list --online

Step 4: install Ubuntu 24.04

wsl --install -d Ubuntu-24.04

If that exact name does not work, list the available distributions:

wsl --list --online

Sample output:

NAME                    FRIENDLY NAME
Ubuntu                  Ubuntu
Ubuntu-26.04            Ubuntu 26.04 LTS
Ubuntu-24.04            Ubuntu 24.04 LTS
Ubuntu-22.04            Ubuntu 22.04 LTS
Debian                  Debian GNU/Linux
kali-linux              Kali Linux Rolling

During the installation you are asked to create a user and a password:

Create a default Unix user account: fernando
New password:
Retype new password:

Step 5: set up SSH access from the Windows host (optional)

To reach the WSL instance from other machines on the local network:

From inside Ubuntu (WSL):

sudo apt update && sudo apt install -y openssh-server
sudo systemctl start ssh
sudo systemctl status ssh

From PowerShell (as administrator), get the WSL IP address:

wsl hostname -I
# Example: 172.27.215.137

Set up port forwarding in Windows to route SSH traffic into WSL:

# Forward host port 2222 to WSL port 22
netsh interface portproxy add v4tov4 listenport=2222 listenaddress=0.0.0.0 connectport=22 connectaddress=172.27.215.137

# Create a firewall rule allowing port 2222
New-NetFirewallRule -DisplayName "WSL SSH 2222" -Direction Inbound -Protocol TCP -LocalPort 2222 -Action Allow

Important: the WSL IP address can change after a reboot. Run wsl hostname -I again if the connection fails.

Connect from another machine:

ssh fernando@192.168.1.83 -p 2222

1.3.2 Install dependencies inside WSL (Ubuntu 24.04)

Once inside Ubuntu (WSL):

sudo apt update && sudo apt upgrade -y
sudo apt install -y \
    git python3.12 python3.12-dev python3.12-venv python3-pip \
    libpq-dev libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev \
    libjpeg-dev zlib1g-dev libfreetype6-dev wkhtmltopdf build-essential wget

2. Create the odoo system user

The odoo user runs the service with minimum privileges.

2.1 Linux (Debian/Ubuntu)

# Create the odoo user with its home directory in /opt/odoo
sudo useradd -m -d /opt/odoo -U -r -s /bin/bash odoo

# Add it to the postgres group (for direct database access)
sudo usermod -aG postgres odoo

# Add it to sudoers (optional, for maintenance)
echo "odoo ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/odoo

2.2 macOS

# Create the odoo user
sudo dscl . -create /Users/odoo
sudo dscl . -create /Users/odoo UserShell /bin/bash
sudo dscl . -create /Users/odoo RealName "Odoo Service"
sudo dscl . -create /Users/odoo UniqueID 1100
sudo dscl . -create /Users/odoo PrimaryGroupID 1000
sudo dscl . -create /Users/odoo NFSHomeDirectory /opt/odoo
sudo dscl . -append /Groups/admin GroupMembership odoo

# Create the home directory
sudo mkdir -p /opt/odoo
sudo chown odoo:admin /opt/odoo

3. Install PostgreSQL

3.1 Linux (Debian/Ubuntu)

sudo apt install -y postgresql
sudo systemctl enable postgresql
sudo systemctl start postgresql

3.2 macOS

brew install postgresql@15
brew services start postgresql@15

3.3 Windows (WSL)

Same as on Linux — PostgreSQL is installed inside WSL.

3.4 Create the PostgreSQL user for Odoo

# Create the PostgreSQL role (no superuser privileges)
sudo -u postgres createuser --createdb --no-superuser --no-createrole odoo

Important: the PostgreSQL user must NOT be a superuser in production. It only needs CREATEDB to create databases.


4. Install Python and the virtual environment

4.1 Check the Python version

python3 --version

4.2 Create the virtual environment

# Switch to the odoo user
sudo su - odoo

# Create the working directory
mkdir -p /opt/odoo
cd /opt/odoo

# Create the virtual environment (use the installed Python version)
python3 -m venv /opt/odoo/odoo-venv

# Activate the virtual environment
source /opt/odoo/odoo-venv/bin/activate

# Upgrade pip
pip install --upgrade pip

4.3 Python versions supported by each Odoo version

Odoo versionRecommended PythonNotes
14.03.6 – 3.9
15.03.8 – 3.10
16.03.10Do not use 3.12 (dependency incompatibilities)
17.03.10 – 3.11
18.03.10 – 3.12
19.03.11 – 3.12

Official source: odoo.com/documentation/18.0/administration/on_premise/source.html


5. Download the Odoo source and the OCA addons with git-aggregator

5.1 Install git-aggregator

# With the virtual environment activated
pip install git-aggregator

5.2 Create repos.yaml

Create the file /opt/odoo/repos.yaml listing the repositories to clone. Replace 18.0 with the Odoo branch you want to install.

Basic structure (example for Odoo 18.0):

/opt/odoo/odoo:
  remotes:
    origin: https://github.com/odoo/odoo.git
  merges:
    - origin 18.0
  target: origin 18.0
  depth: 1

/opt/odoo/addons/account-analytic:
  remotes:
    origin: https://github.com/OCA/account-analytic.git
  merges:
    - origin 18.0
  target: origin 18.0
  depth: 1

/opt/odoo/addons/account-financial-tools:
  remotes:
    origin: https://github.com/OCA/account-financial-tools.git
  merges:
    - origin 18.0
  target: origin 18.0
  depth: 1

/opt/odoo/addons/account-invoicing:
  remotes:
    origin: https://github.com/OCA/account-invoicing.git
  merges:
    - origin 18.0
  target: origin 18.0
  depth: 1

/opt/odoo/addons/l10n-spain:
  remotes:
    origin: https://github.com/OCA/l10n-spain.git
  merges:
    - origin 18.0
  target: origin 18.0
  depth: 1

/opt/odoo/addons/server-tools:
  remotes:
    origin: https://github.com/OCA/server-tools.git
  merges:
    - origin 18.0
  target: origin 18.0
  depth: 1

/opt/odoo/addons/web:
  remotes:
    origin: https://github.com/OCA/web.git
  merges:
    - origin 18.0
  target: origin 18.0
  depth: 1

Structure for Odoo 16.0 (change the branch to 16.0):

/opt/odoo/odoo:
  remotes:
    origin: https://github.com/odoo/odoo.git
  merges:
    - origin 16.0
  target: origin 16.0
  depth: 1

/opt/odoo/addons/l10n-spain:
  remotes:
    origin: https://github.com/OCA/l10n-spain.git
  merges:
    - origin 16.0
  target: origin 16.0
  depth: 1

The depth: 1 key performs a shallow clone that downloads only the last commit of the branch, cutting download time and disk usage significantly.

Popular OCA repositories: the full catalogue is at github.com/OCA

5.3 Run git-aggregator

# With the virtual environment activated and as the odoo user
cd /opt/odoo
gitaggregate -c /opt/odoo/repos.yaml

5.4 Resulting structure

/opt/odoo/
├── repos.yaml              # git-aggregator configuration
├── odoo-venv/              # Python virtual environment
├── odoo/                   # Odoo source code (cloned by git-aggregator)
│   ├── odoo-bin
│   ├── addons/             # Odoo core modules
│   └── ...
├── addons/                 # OCA repositories (cloned by git-aggregator)
│   ├── l10n-spain/
│   │   ├── l10n_es/
│   │   ├── l10n_es_aeat/
│   │   └── requirements.txt
│   ├── account-financial-tools/
│   └── ...
├── conf/                   # Configuration files
│   └── odoo.conf
├── data/                   # Odoo data (filestore, sessions)
└── scripts/                # Start-up scripts
    └── odoo-launcher.sh

6. Install the Python dependencies

6.1 Odoo core dependencies

# With the virtual environment activated
pip install -r /opt/odoo/odoo/requirements.txt

6.2 OCA repository dependencies

# Find and install every requirements.txt from the OCA addons automatically
find /opt/odoo/addons -maxdepth 2 -name requirements.txt -exec \
    /opt/odoo/odoo-venv/bin/pip install --quiet -r {} \; 2>&1 | tail -20 || true

What this does: the search walks the OCA repositories under /opt/odoo/addons/ down to a maximum depth of 2 (repository root plus one subdirectory), locates every requirements.txt and runs pip install on it. The || true prevents the script from failing when a repository has no requirements.txt. Depth 2 is used because OCA repos keep their requirements.txt either at the repository root or one directory below.

6.3 Additional recommended dependencies

pip install \
    phonenumbers \
    num2words \
    PyPDF2 \
    python-stdnum \
    pytz \
    requests \
    simplejson \
    vatnumber \
    vcard \
    openpyxl \
    xlsxwriter

6.4 System dependencies for PDF reports

# Linux (Debian/Ubuntu) - wkhtmltopdf ships in the official repositories
sudo apt install -y wkhtmltopdf

# macOS
brew install wkhtmltopdf

# Check the installation
wkhtmltopdf --version

Recommended wkhtmltopdf version: 0.12.6.1 or newer. See the compatibility table in section 12.


7. Configure Odoo

7.1 Create the directories

sudo mkdir -p /opt/odoo/conf
sudo mkdir -p /opt/odoo/data
sudo chown -R odoo:odoo /opt/odoo/conf /opt/odoo/data

7.2 Create the odoo.conf file

cat > /opt/odoo/conf/odoo.conf << 'EOF'
[options]
; PostgreSQL connection
db_host = localhost
db_port = 5432
db_user = odoo
db_password = False

; Administrator password (change it in production)
admin_passwd = admin

; Directories
addons_path = /opt/odoo/odoo/addons,/opt/odoo/addons
data_dir = /opt/odoo/data

; Network settings
proxy_mode = False

; Worker settings (0 = threading, N = prefork)
workers = 0
max_cron_threads = 1

; Memory limits (in bytes, only applied when workers > 0)
limit_memory_hard = 2684354560
limit_memory_soft = 2147483648
limit_request = 8192
limit_time_cpu = 60
limit_time_real = 120

; Demo data (False = no demo data)
without_demo = False

; Database
db_template = template1
EOF

7.3 Assign permissions by operating system

Linux (Debian/Ubuntu)

sudo chown odoo:odoo /opt/odoo/conf/odoo.conf
sudo chmod 640 /opt/odoo/conf/odoo.conf

macOS

sudo chown odoo:admin /opt/odoo/conf/odoo.conf
sudo chmod 640 /opt/odoo/conf/odoo.conf

About data_dir: this parameter tells Odoo where to keep the filestore (attachments), sessions, cache and other temporary data. In this configuration it points to /opt/odoo/data.


8. Launcher with a dynamic addons_path

The launcher builds --addons-path on the fly by scanning the repositories cloned under /opt/odoo/addons/ and keeping only the directories that actually contain modules (those with an __manifest__.py). That way, adding or removing repositories with git-aggregator never means editing the configuration file by hand.

8.1 Create the launcher script

cat > /opt/odoo/scripts/odoo-launcher.sh << 'LAUNCHER'
#!/bin/bash
set -e

ODOO_BIN="/opt/odoo/odoo/odoo-bin"
ODOO_CONF="/opt/odoo/conf/odoo.conf"
PYTHON="/opt/odoo/odoo-venv/bin/python3"
ADDONS_BASE="/opt/odoo/odoo/addons"
ADDONS_OCA="/opt/odoo/addons"

ADDONS_PATH="${ADDONS_BASE}"

if [ -d "${ADDONS_OCA}" ]; then
    for dir in "${ADDONS_OCA}"/*/; do
        if [ -d "$dir" ]; then
            if find "$dir" -maxdepth 2 -name __manifest__.py -print -quit 2>/dev/null | grep -q .; then
                ADDONS_PATH="${ADDONS_PATH},${dir%/}"
            fi
        fi
    done
fi

if [ "$1" = "shell" ]; then
    shift
    exec "${PYTHON}" "${ODOO_BIN}" shell \
        --config="${ODOO_CONF}" \
        --addons-path="${ADDONS_PATH}" \
        "$@"
elif [ "$1" = "init" ]; then
    DB=${2:-odoo}
    shift 2
    exec "${PYTHON}" "${ODOO_BIN}" \
        --config="${ODOO_CONF}" \
        --addons-path="${ADDONS_PATH}" \
        -d "${DB}" -i base --stop-after-init --no-http --workers=0 \
        "$@"
else
    exec "${PYTHON}" "${ODOO_BIN}" \
        --config="${ODOO_CONF}" \
        --addons-path="${ADDONS_PATH}" \
        "$@"
fi
LAUNCHER

chmod +x /opt/odoo/scripts/odoo-launcher.sh

8.2 Using the launcher

# Start Odoo normally
/opt/odoo/scripts/odoo-launcher.sh --http-port=8069

# Open the Odoo shell
/opt/odoo/scripts/odoo-launcher.sh shell

# Create the initial database
/opt/odoo/scripts/odoo-launcher.sh init my_database

9. Start Odoo

9.1 Development mode (directly)

# Switch to the odoo user
sudo su - odoo

# Start with the dynamic launcher (it uses the venv interpreter itself)
/opt/odoo/scripts/odoo-launcher.sh --http-port=8069

9.2 Create the initial database

# In the browser, go to:
# http://localhost:8069/web/database/manager

# Or from the command line:
/opt/odoo/scripts/odoo-launcher.sh init my_database

9.3 systemd service (production)

cat > /tmp/odoo.service << 'EOF'
[Unit]
Description=Odoo 18.0
After=network.target postgresql.service

[Service]
Type=simple
SyslogIdentifier=odoo
PermissionsStartOnly=true
User=odoo
Group=odoo
ExecStart=/opt/odoo/scripts/odoo-launcher.sh
StandardOutput=journal+console

[Install]
WantedBy=multi-user.target
EOF

sudo cp /tmp/odoo.service /etc/systemd/system/odoo.service

# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable odoo
sudo systemctl start odoo

# Follow the logs
sudo journalctl -u odoo -f

10. Compatibility table by version

VersionPythonPostgreSQLDebianUbuntuwkhtmltopdfNotes
14.03.6-3.910-141118.04-20.040.12.5
15.03.8-3.1010-1411-1220.04-22.040.12.5
16.03.1012-151222.040.12.6.1Do not use Python 3.12
17.03.10-3.1112-151222.04-24.040.12.6.1
18.03.10-3.1212-1612-1322.04-24.040.12.6.1
19.03.11-3.1214-161324.040.12.6.1

Source: the vendor's own compatibility tables at odoo.com/documentation/18.0/administration/on_premise/packages.html


11. Dependency tables by version

Source: direct analysis of the requirements.txt files in the official Odoo repository (github.com/odoo/odoo) for each branch. The values are the exact versions Odoo installs by default. Values in bold are critical pins that must NOT be changed.

11.1 Odoo 16.0 (Python 3.10, Ubuntu 22.04 Jammy)

PackageVersionNotes
Babel2.9.1
chardet4.0.0
cryptography3.4.8Do not use >= 37.0 on Python < 3.12
decorator4.4.2
docutils0.16
ebaysdk2.1.5
freezegun0.3.15
gevent22.10.2Only for Python > 3.10 and < 3.12
greenlet2.0.2Only for Python > 3.10 and < 3.12
idna2.10
Jinja23.1.2For Python > 3.10
libsass0.20.1For Python < 3.12
lxml4.9.3For Python > 3.10 and < 3.12
MarkupSafe2.1.2For Python > 3.10 and < 3.12
num2words0.5.9
ofxparse0.21
passlib1.7.4
Pillow9.4.0For Python > 3.10 and < 3.12
polib1.1.0
psutil5.9.4For Python > 3.10 and < 3.12
psycopg22.9.5For Python >= 3.11 and < 3.12
PyDot1.4.2
pyparsing2.4.7
pyserial3.5
python-dateutil2.8.2
python-stdnum1.17
pytz2022.7
qrcode7.4.2
reportlab3.6.12
requests2.28.2
rjsmin1.0.1
simplejson3.19.1
six1.16.0
urllib31.26.5
vobject0.9.6.1
Werkzeug2.0.2Do not use >= 2.1
xlrd2.0.1
xlwt1.3.0
xlsxwriter3.0.3
xlwings0.29.12Windows only

11.2 Odoo 18.0 (Python 3.10-3.12, Ubuntu 22.04 / 24.04)

PackageVersion (Py 3.10)Version (Py >= 3.12)Notes
Babel2.9.12.9.1
chardet4.0.04.0.0
cryptography3.4.842.0.8
decorator4.4.24.4.2
docutils0.170.20.1
freezegun0.3.150.3.15
gevent21.8.024.2.1
greenlet1.1.23.0.3
idna2.102.10
Jinja22.11.33.1.2
libsass0.20.10.22.0
lxml4.6.55.2.1
MarkupSafe1.1.12.1.5
num2words0.5.120.5.12
ofxparse0.210.21
passlib1.7.41.7.4
Pillow9.0.110.2.0
polib1.1.01.1.0
psutil5.8.05.9.8
psycopg22.9.22.9.9
PyPDF23.0.13.0.1
PySocks1.7.11.7.1
python-dateutil2.8.22.9.0
python-stdnum1.171.17
pytz2022.72024.1
qrcode7.4.27.4.2
reportlab4.0.84.1.0
requests2.31.02.31.0
rjsmin1.2.01.2.0
simplejson3.19.23.19.2
urllib32.0.72.2.2
vobject0.9.6.10.9.6.1
Werkzeug2.3.83.0.6
xlrd2.0.12.0.1
xlsxwriter3.1.93.1.9
xlwings0.29.120.30.10Windows only
zeep4.2.14.2.1

11.3 Odoo 19.0 (Python 3.11-3.12, Debian 13 / Ubuntu 24.04)

PackageVersionNotes
Babel2.15.0
chardet4.0.0
cryptography43.0.3
decorator4.4.2
docutils0.21.1
gevent24.11.1
greenlet3.1.1
Jinja23.1.4
lxml5.3.0
MarkupSafe2.1.5
num2words0.5.13
passlib1.7.4
Pillow10.4.0
polib1.2.0
psutil5.9.8
psycopg22.9.9
PyPDF23.0.1
python-dateutil2.9.0
python-stdnum1.17
pytz2024.2
qrcode7.4.2
reportlab4.2.2
requests2.32.3
rjsmin1.2.0
simplejson3.19.2
Werkzeug3.1.3
xlrd2.0.1
xlsxwriter3.2.0

12. wkhtmltopdf table by distribution

Distributionapt packageShipped versionRecommended version
Debian 11 (Bullseye)wkhtmltopdf0.12.6-10.12.6-1
Debian 12 (Bookworm)wkhtmltopdf0.12.6-2+b10.12.6-2+b1
Debian 13 (Trixie)wkhtmltopdf0.12.6-2+b10.12.6-2+b1
Ubuntu 20.04 (Focal)wkhtmltopdf0.12.5-10.12.5-1
Ubuntu 22.04 (Jammy)wkhtmltopdf0.12.6.1-20.12.6.1-2 (recommended)
Ubuntu 24.04 (Noble)wkhtmltopdf0.12.6.1-20.12.6.1-2 (recommended)

12.1 Manual installation (when the repository version is not enough)

Download from github.com/wkhtmltopdf/packaging/releases:

Operating systemArchitecturePackage
Ubuntu 22.04 (Jammy)amd64wkhtmltox_0.12.6.1-3.jammy_amd64.deb
Ubuntu 22.04 (Jammy)arm64wkhtmltox_0.12.6.1-3.jammy_arm64.deb
Ubuntu 20.04 (Focal)amd64wkhtmltox_0.12.6-1.focal_amd64.deb
Debian 12 (Bookworm)amd64wkhtmltox_0.12.6.1-3.bookworm_amd64.deb
Debian 12 (Bookworm)arm64wkhtmltox_0.12.6.1-3.bookworm_arm64.deb
Debian 11 (Bullseye)amd64wkhtmltox_0.12.6.1-3.bullseye_amd64.deb
Debian 11 (Bullseye)arm64wkhtmltox_0.12.6.1-3.bullseye_arm64.deb
macOScocoawkhtmltox-0.12.6-2.macos-cocoa.pkg

Ubuntu 24.04 (Noble): upstream publishes no package for Noble. Install it from the distribution repositories (sudo apt install -y wkhtmltopdf, which ships 0.12.6.1-2) or use the Jammy build, which works on Noble.


13. Common troubleshooting

13.1 Error "psycopg2" when installing the dependencies

# Install libpq-dev (the PostgreSQL headers)
sudo apt install -y libpq-dev

# If that fails, install from a wheel
pip install psycopg2-binary

13.2 Error "wkhtmltopdf" not found

# Install from the official repositories
sudo apt install -y wkhtmltopdf

# If the repository version is too old, install it manually.
# Every available version is listed at:
# https://github.com/wkhtmltopdf/packaging/releases

13.3 Database permission error

# Check that the odoo role exists in PostgreSQL
sudo -u postgres psql -c "\du odoo"

# If it does not, create it:
sudo -u postgres createuser --createdb --no-superuser odoo

13.4 Error: "gevent" does not compile

# Install the build dependencies
sudo apt install -y python3-dev build-essential libffi-dev

# For Odoo 16.0, pin the versions:
pip install gevent==22.10.2 greenlet==2.0.2

13.5 Odoo will not start: "addons path not found"

# Check that the paths exist
ls -la /opt/odoo/odoo/addons
ls -la /opt/odoo/addons

# Run the launcher directly to see the path it builds
/opt/odoo/scripts/odoo-launcher.sh --http-port=8069

13.6 WSL: "WSL2 cannot start because virtualization is not enabled"

This error shows up when the Virtual Machine Platform is not enabled in Windows.

# Fix 1: enable the Virtual Machine Platform
# Open Control Panel > Turn Windows features on or off
# Tick "Virtual Machine Platform"
# Restart the machine

# Fix 2: enable virtualization in the BIOS/UEFI
# Restart the machine > enter the BIOS (F2/F10/Del)
# Look for the CPU > Advanced section
# Enable Intel VT-x (Intel) or AMD-V (AMD)
# Save and reboot

# Fix 3: on virtual machines (Proxmox, VMware, VirtualBox)
# Enable nested virtualization in the VM settings
# Proxmox: VM > Options > Processor > vCPU type = host
# VMware: VM > Settings > Processor > Virtualize Intel VT-x/EPT
# VirtualBox: VM > Settings > System > Acceleration > Enable VT-x/AMD-V

13.7 WSL: the WSL IP address changes after a reboot

# Get the new WSL IP address
wsl hostname -I

# Update the port forwarding
netsh interface portproxy delete v4tov4 listenport=2222 listenaddress=0.0.0.0
netsh interface portproxy add v4tov4 listenport=2222 listenaddress=0.0.0.0 connectport=22 connectaddress=<NEW_IP>

13.8 WSL: SSH does not work from the host

# Check that the SSH service is running inside WSL
wsl -d Ubuntu-24.04 -u root -- service ssh status

# Restart the SSH service if needed
wsl -d Ubuntu-24.04 -u root -- service ssh restart

# Check the firewall rule
Get-NetFirewallRule -DisplayName "WSL SSH 2222"

# If it is missing, create it again
New-NetFirewallRule -DisplayName "WSL SSH 2222" -Direction Inbound -Protocol TCP -LocalPort 2222 -Action Allow

References

Can AI fix my phone?
A phone that "broke" and showed every image in black and white. Two minutes of setup, one prompt, and a diagnosis nobody expected.