← Back to OdooWoo
Guide · 25 min read

Install Odoo from source on Ubuntu

Switch versions to get the exact commands for Odoo 16, 17, 18, or 19. Each preset updates users, paths, and ports automatically. The stack provisions Ubuntu packages, a Python virtualenv, Redis, PostgreSQL, wkhtmltopdf, a hardened systemd service with logrotate, Nginx with Certbot, and the OdooWoo helper module so your Odoo + WooCommerce integration is production-ready end to end.

Need the helper steps only? Jump to the OdooWoo helper module guide or contact our team for a review before production.

Version

Customize variables

Update these once and the commands below will respect your values.

Before you begin

This guide uses Nano to create and edit files. Save with Ctrl+S then Enter; exit with Ctrl+X then Enter. Every command uses sudo, which you can omit if logged in as root.

Commands below are shown for Odoo 18. Adjust user names, paths, and ports when running multiple versions side-by-side.

1. Create system user and directories

Set up a dedicated home tree for this release. Permissions at 755 let sudo-capable users inspect the directory without switching accounts.

sudo adduser --system --home /opt/odoo18 --group --shell /bin/bash odoo18
sudo mkdir -p /opt/odoo18/{custom-addons,src} sudo chown -R odoo18:odoo18 /opt/odoo18 sudo chmod 755 /opt/odoo18

2. Install system packages and Python virtualenv

Install compile dependencies, then create a virtualenv scoped to this release.

Setuptools is pinned below 81 (80.1.0) so Odoo can keep using pkg_resources without the deprecation warning.

sudo apt update sudo apt -y install python3 python3-venv python3-pip build-essential libpq-dev libldap2-dev libsasl2-dev libxml2-dev libxslt1-dev zlib1g-dev libjpeg-dev libtiff5-dev libopenjp2-7 libffi-dev
sudo -u odoo18 python3 -m venv /opt/odoo18/venv sudo -u odoo18 /opt/odoo18/venv/bin/pip install --upgrade pip wheel
sudo -u odoo18 /opt/odoo18/venv/bin/pip install "setuptools==80.1.0"

3. Install Redis (recommended)

Install Redis once per server so Odoo longpolling bus, cron jobs, and queue workers have a fast in-memory backend.

Enable systemd supervision so Redis restarts automatically with the host.

sudo apt -y install redis-server
sudo sed -i "s/^supervised .*/supervised systemd/" /etc/redis/redis.conf sudo systemctl enable --now redis-server sudo systemctl status redis-server

4. Clone Odoo source

Clone the Odoo 18 branch into the src directory.

sudo -u odoo18 -H bash -c ' cd /opt/odoo18/src git clone --depth 1 --branch 18.0 https://github.com/odoo/odoo.git'

5. Install Python requirements

sudo -u odoo18 -H bash -c ' /opt/odoo18/venv/bin/pip install -r /opt/odoo18/src/odoo/requirements.txt'

6. (Optional) RTL language support

sudo apt -y install nodejs npm sudo npm install -g rtlcss

7. Install wkhtmltopdf 0.12.6

Use the official Qt-patched 0.12.6 package for Jammy/Noble to keep PDF reports healthy.

sudo apt -y install xfonts-75dpi fontconfig libxrender1 libxext6 libx11-6
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb sudo apt -y install ./wkhtmltox_0.12.6-1.focal_amd64.deb
sudo ln -sf /usr/local/bin/wkhtmltopdf /usr/bin/wkhtmltopdf sudo ln -sf /usr/local/bin/wkhtmltoimage /usr/bin/wkhtmltoimage wkhtmltopdf --version

8. Set up PostgreSQL

These commands assume the default postgres administrator user exists. If PostgreSQL is not installed yet, install it first.

Update the password to something stronger than "odoo18_db_pass" and reuse it in the config file below.

sudo apt -y install postgresql postgresql-contrib
sudo -u postgres createuser -d -R -S odoo18 sudo -u postgres createdb -O odoo18 odoo18 sudo -u postgres psql -c "ALTER USER odoo18 WITH PASSWORD 'odoo18_db_pass';"

9. Create Odoo config file

Create the configuration directory and the config file.

sudo mkdir -p /etc/odoo /var/log/odoo sudo chown odoo18:odoo18 /etc/odoo /var/log/odoo
sudo -u odoo18 tee /etc/odoo/odoo18.conf > /dev/null <<'EOF' [options] admin_passwd = admin1234# db_host = 127.0.0.1 db_port = 5432 db_user = odoo18 db_password = odoo18_db_pass db_name = odoo18 http_port = 8089 gevent_port = 8092 addons_path = /opt/odoo18/src/odoo/addons,/opt/odoo18/custom-addons logfile = /var/log/odoo/odoo18.log proxy_mode = True workers = 3 max_cron_threads = 1 limit_time_cpu = 600 limit_time_real = 1200 limit_memory_soft = 671088640 limit_memory_hard = 805306368 EOF

10. Create systemd service

sudo tee /etc/systemd/system/odoo18.service >/dev/null <<'EOF' [Unit] Description=Odoo 18.0 (Source Install) After=network.target postgresql.service Requires=postgresql.service [Service] Type=simple User=odoo18 Group=odoo18 WorkingDirectory=/opt/odoo18/src/odoo ExecStart=/opt/odoo18/venv/bin/python3 /opt/odoo18/src/odoo/odoo-bin -c /etc/odoo/odoo18.conf Restart=on-failure TimeoutStopSec=60 KillMode=mixed [Install] WantedBy=multi-user.target EOF
sudo systemctl daemon-reload sudo systemctl enable --now odoo18 sudo systemctl status odoo18

11. Nginx reverse proxy and HTTPS

Run these as root/sudo so Nginx can read its PID and reload cleanly.

sudo apt -y install nginx
sudo tee /etc/nginx/sites-available/odoo.conf >/dev/null <<'EOF' upstream odoo { server 127.0.0.1:8089; } upstream odoochat { server 127.0.0.1:8092; } server { listen 80; server_name odoo.example.com; location /websocket { proxy_pass http://odoochat; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location / { proxy_pass http://odoo; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; } } EOF
sudo ln -s /etc/nginx/sites-available/odoo.conf /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx
sudo apt -y install certbot python3-certbot-nginx sudo certbot --nginx -d odoo.example.com

12. Install OdooWoo helper module

Place the OdooWoo helper module in custom-addons before you initialize the database so it is ready to install once you log in.

Re-running this command refreshes the module contents from GitHub.

sudo -u odoo18 bash -c ' cd /opt/odoo18/custom-addons git clone https://github.com/beltoftandersen/odoowoo-helper-module.git odoowoo-helper-module 2>/dev/null || (cd odoowoo-helper-module && git pull --ff-only)'

13. Initialize the database

Stop the service, run a one-time initialization with no demo data, set the admin login password, then bring it back online.

This installs the base apps (base,sale_management,account,stock,odoowoo-helper-module).

The master password for database operations still lives in /etc/odoo/odoo18.conf (admin_passwd from Step 9); the shell snippet below updates the admin user's login password to admin1234#.

sudo systemctl stop odoo18
sudo -u odoo18 /opt/odoo18/venv/bin/python3 /opt/odoo18/src/odoo/odoo-bin -c /etc/odoo/odoo18.conf -d odoo18 -i base,sale_management,account,stock,odoowoo-helper-module --without-demo=all --stop-after-init
sudo -u odoo18 /opt/odoo18/venv/bin/python3 /opt/odoo18/src/odoo/odoo-bin shell -c /etc/odoo/odoo18.conf -d odoo18 <<'EOF' user = env['res.users'].search([('login', '=', 'admin')], limit=1) user.password = 'admin1234#' env.cr.commit() EOF
sudo systemctl start odoo18 sudo systemctl status odoo18

14. Access Odoo

Open https://odoo.example.com, log in with the admin password you configured (admin1234#), and verify everything loads correctly.

Repeat the same steps for other releases -- just adjust usernames, branches, and ports.

Next steps