Choose the release and size the server before you start
Odoo Community is a Python application with a PostgreSQL database and a PDF renderer beside it. The release you install decides the Python version, and the number of people using it decides the RAM. Decide both before the first command.
| Use | vCPU | RAM | Notes |
|---|---|---|---|
| Trial or single user | 1 | 2 GB | Works with 1 worker, no room for growth |
| Small team, up to 5 users | 2 | 4 GB | PostgreSQL, Odoo, and Nginx on one box |
| 10 to 15 concurrent users | 4 | 8 GB | Room for 5 workers plus cron and the database |
Odoo 17 and later require Python 3.10 or newer, and Ubuntu 24.04 ships 3.12, so the system Python is enough. Pick one release branch (18.0 or 19.0) and stay on it; mixing branches in one database is not supported. A VPS server with root access is the minimum, because Odoo needs its own system user and a service unit.
Install the packages, PostgreSQL and wkhtmltopdf
The dependencies are ordinary Ubuntu packages plus one downloaded .deb for PDF reports. Run these as a sudo user, not as root, and read the PostgreSQL line carefully because the Odoo user must exist there too.
- Run
sudo apt update && sudo apt -y upgrade, then install the build tools:sudo apt install git python3-pip python3-venv python3-dev build-essential libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev libpq-dev libjpeg-dev zlib1g-dev. - Install the database:
sudo apt install postgresql postgresql-client. Ubuntu 24.04 ships PostgreSQL 16. - Create the Odoo system user with
sudo useradd -m -d /opt/odoo -U -r -s /bin/bash odoo. - Create a PostgreSQL superuser of the same name:
sudo su - postgres -c "createuser -s odoo". Without the -s flag, creating a database from the Odoo UI fails later. - Download the wkhtmltopdf build for your Ubuntu release from the wkhtmltopdf packaging releases page, install it with
sudo apt install ./wkhtmltox_*.deb, and check it withwkhtmltopdf --version.
wkhtmltopdf is the step people skip, and the symptom is specific: everything works until someone prints a quotation and gets a blank PDF or a server error. Version 0.12.6 with patched Qt is the build Odoo expects; the unpatched build in some distributions cannot render headers and footers.
Pull the source into a virtual environment
Odoo runs from a checkout of its own repository, inside a Python virtual environment owned by the odoo user. This keeps Odoo's dependencies away from the system Python.
- Switch to the service user with
sudo su - odoo. - Clone one branch:
git clone https://github.com/odoo/odoo --depth 1 --branch 18.0 /opt/odoo/odoo-server. - Create and activate the environment:
python3 -m venv /opt/odoo/venvthensource /opt/odoo/venv/bin/activate. - Install dependencies:
pip install --upgrade pip wheeland thenpip install -r /opt/odoo/.odoo-server/ requirements. txt - Create a custom addons folder with
mkdir /opt/odoo/custom-addons, so your own modules never sit inside the git checkout.
You know this step worked when python /opt/odoo/ prints the release number. If pip fails on a C extension, the build tools from the previous section are missing, not the package.
Write odoo.conf and a systemd unit
Two files turn a folder of Python into a service that starts at boot. The configuration file holds the database connection and the master password; the unit file tells systemd how to run it.
admin_passwdin/etc/odoo/odoo.confis the master password for creating, backing up, and dropping databases. Set it to a long random string and keep it out of the repository.db_host = Falseanddb_user = odoouse the local Unix socket and peer authentication, which is simpler and safer than a password over TCP.addons_pathlists the core addons folder first, then your custom folder.proxy_mode = Trueis required once Nginx sits in front, or Odoo logs the proxy IP for every request.- The unit runs as
User=odoo, withExecStart=and/opt/odoo/ venv/bin/python3 /opt/odoo/ odoo-server/ odoo-bin -c /etc/odoo/odoo.conf After=network.target postgresql.service.
Then run sudo systemctl daemon-reload, sudo systemctl enable --now odoo, and check with systemctl status odoo. Confirm the port with curl -I http://127.0.0.1:8069: a 200 or a 303 means the service is alive before Nginx is involved.
Put Nginx in front and add HTTPS
Odoo serves plain HTTP on 8069 and a websocket-style longpolling endpoint on 8072. Nginx terminates TLS and forwards both, and the longpolling block is what keeps the chatter and notifications connected.
In the server block, proxy location / to 127.0.0.1:8069 and location /longpolling to 127.0.0.1:8072. Keep proxy_set_header Host $host, X-Real-IP, X-Forwarded-For, and X-Forwarded-Proto $scheme, and raise the proxy timeouts to about 720 seconds so long reports do not time out.
Run sudo nginx -t before every reload, then sudo certbot --nginx -d odoo.example.com for the certificate. Confirm proxy_mode = True is in odoo.conf and restart the service. Open the domain: the Odoo login page over https is the finish line.
First login: master password, database, and apps
Open https://your- and create a database with the master password from odoo.conf. Pick a database name, set the administrator email and password, and load the demo data only on a test instance.
Inside the app, install the modules you actually need from Apps. Every install adds tables and load time, so start with Sales, Invoicing, and Inventory rather than the full suite. Then note two paths for backup: the database dump and the filestore folder under /opt/odoo/, which holds attachments and must be copied with the dump.
A dump without the filestore restores to a database where every attachment is missing. That is the single most common Odoo backup mistake, and it surfaces weeks later when someone opens an old invoice.
Workers, memory limits, and the errors that follow
Out of the box Odoo runs in threaded mode, which is fine for one or two users. For a team, switch to multiprocessing with a worker count based on cores: the usual formula is twice the cores plus one, with each worker serving about six concurrent users.
On a 4-core, 8 GB machine that is five workers plus one cron thread, and roughly 2 GB reserved for them. Set workers, max_cron_threads = 1, limit_memory_hard and limit_memory_soft in odoo.conf, then restart. The hard limit recycles a worker that leaks instead of letting the kernel kill the whole service.
| Symptom | Cause | Fix |
|---|---|---|
| 502 Bad Gateway from Nginx | Odoo is not running or not on 8069 | systemctl status odoo, then journalctl -u odoo -n 50 |
| Blank PDF for quotations | wkhtmltopdf missing or unpatched Qt build | Install the 0.12.6 patched build and restart |
| Connection Lost popup in chatter | /longpolling is not proxied to 8072 | Add the longpolling location block and reload Nginx |
| Permission denied writing filestore | Files owned by root after a manual copy | chown -R odoo:odoo /opt/odoo and the filestore path |
| Database creation fails from the UI | The PostgreSQL role is not a superuser | sudo su - postgres -c "createuser -s odoo" |
Odoo hosting from WebJi
If you would rather not run the stack yourself, Odoo hosting covers the server, PostgreSQL, the service unit, and certificate renewals. If you want root and your own modules, a VPS with a separate PostgreSQL database is the cleaner split once a second app shares the machine.
VPS and Odoo configurations are quoted by email at support@webji.services before you pay, because RAM, disk, and backup retention set the price. Support is 24/7 by email in Hindi and English, with an average first reply under 60 minutes.
Frequently Asked Questions
Can Odoo run on a 2 GB VPS?
Yes, for a trial or a single user with one worker. A small team needs 4 GB because PostgreSQL, Odoo, and Nginx share the machine, and 10 to 15 concurrent users need about 8 GB to run five workers plus cron without swapping.
Which Ubuntu version should I use for Odoo?
Ubuntu 24.04 LTS. It ships Python 3.12, which satisfies the Python 3.10 minimum for Odoo 17 and later, and PostgreSQL 16 from the standard repositories. Ubuntu 22.04 also works if you are already standardised on it.
Why does Nginx return 502 Bad Gateway for Odoo?
The proxy is running but Odoo is not listening. Check systemctl status odoo and read journalctl -u odoo for the traceback, then confirm with curl -I http://127.0.0.1:8069. A configuration typo in odoo.conf or a missing Python dependency stops the service at start.
How do I install wkhtmltopdf for Odoo?
Download the 0.12.6 build with patched Qt for your Ubuntu release from the wkhtmltopdf packaging releases, install it with apt install ./wkhtmltox_*.deb, and verify with wkhtmltopdf --version. The unpatched build produces blank or unstyled PDF reports.
How many Odoo workers should I run?
Start from twice the CPU cores plus one, then check against users: each worker serves roughly six concurrent users. On 4 cores and 8 GB, five workers plus one cron thread fits, with memory limits set so a leaking worker is recycled rather than taking the service down.
Is Odoo Community free for commercial use?
Yes. Odoo Community is open source under LGPL version 3 and can be self-hosted for commercial use without a licence fee. The paid Enterprise edition adds apps and support, and Odoo Online is Odoo's own hosted service, which is a different product from your own installation.

