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.
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 odoo18sudo mkdir -p /opt/odoo18/{custom-addons,src}
sudo chown -R odoo18:odoo18 /opt/odoo18
sudo chmod 755 /opt/odoo182. 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-devsudo -u odoo18 python3 -m venv /opt/odoo18/venv
sudo -u odoo18 /opt/odoo18/venv/bin/pip install --upgrade pip wheelsudo -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-serversudo sed -i "s/^supervised .*/supervised systemd/" /etc/redis/redis.conf
sudo systemctl enable --now redis-server
sudo systemctl status redis-server4. 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 rtlcss7. 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-6wget 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.debsudo ln -sf /usr/local/bin/wkhtmltopdf /usr/bin/wkhtmltopdf
sudo ln -sf /usr/local/bin/wkhtmltoimage /usr/bin/wkhtmltoimage
wkhtmltopdf --version8. 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-contribsudo -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/odoosudo -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
EOF10. 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
EOFsudo systemctl daemon-reload
sudo systemctl enable --now odoo18
sudo systemctl status odoo1811. Nginx reverse proxy and HTTPS
Run these as root/sudo so Nginx can read its PID and reload cleanly.
sudo apt -y install nginxsudo 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;
}
}
EOFsudo ln -s /etc/nginx/sites-available/odoo.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxsudo apt -y install certbot python3-certbot-nginx
sudo certbot --nginx -d odoo.example.com12. 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 odoo18sudo -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-initsudo -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()
EOFsudo systemctl start odoo18
sudo systemctl status odoo1814. 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
- Need to install or update just the helper module? OdooWoo helper module guide
- Ready to connect WooCommerce? Back to the OdooWoo overview