How to Install Odoo on a VPS
Install a pinned Odoo release with its supported Python, PostgreSQL and report-rendering dependencies, using a dedicated Unix account and non-superuser database role. Run it through a service unit, then configure HTTPS and the release’s websocket proxy route. Protect the database manager and test database-plus-filestore recovery before exposing production data; capacity requires workload-specific measurement.
For administrators self-hosting Odoo 18, with branch-specific dependencies, least-privilege database access and public-proxy safeguards rather than unmeasured user-count limits.
knowledge
- Read time
- 5 min
- Sections
- 8
- Updated
- 14 Nov 2026
- Written by
- WebJi® team
Last editorial update: 14 November 2026.
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.
| Component | Planning question |
|---|---|
| Odoo workers | Which modules and concurrent operations are measured? |
| PostgreSQL | Database size, working set and backup load? |
| Filestore | Attachment volume, growth and recovery storage? |
| Proxy and evented service | HTTP, HTTPS and websocket configuration tested? |
This source-install example uses Odoo 18.0. Its official requirements specify Python 3.10 or later and PostgreSQL 12 or later. Verify dependencies for the branch actually installed; do not reuse one database across incompatible branches.
Install the packages, PostgreSQL and wkhtmltopdf
Install the supported system dependencies before starting Odoo, and create a dedicated Unix service account rather than running the application as root. Give that account an owned home and application directory, then create a matching PostgreSQL role with only the required privileges.
sudo apt update
sudo apt install git python3-venv postgresql postgresql-client
sudo -u postgres createuser -d -R -S odooThe role command assumes the odoo Unix account has already been created. Install the branch’s documented build dependencies before pip requirements. Odoo 18 documentation requires the supported wkhtmltopdf 0.12.6 build for report headers and footers; choose the package matching the OS and architecture.
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/odoo-server/odoo-bin --version 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=/opt/odoo/venv/bin/python3 /opt/odoo/odoo-server/odoo-bin -c /etc/odoo/odoo.confandAfter=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.
For Odoo 18 multiprocessing deployments, route normal requests to the HTTP service and /websocket to the evented service using the official Nginx example. Configure the forwarding headers deliberately and enable proxy_mode only behind a trusted proxy. Do not substitute the obsolete /longpolling route or a blanket guessed timeout.
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
Odoo database provisioning should be controlled privately, then database selection and manager exposure restricted before public operation. Open https://your-domain/web/database/manager 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.
Record the effective data_dir and its filestore location alongside the database recovery procedure. Attachments and the database must be captured coherently; a hardcoded home path is not reliable across every installation.
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
Odoo’s default threaded mode suits development and demonstrations; production multiprocessing requires explicit worker and evented-proxy configuration. Official sizing examples are planning heuristics, not measured capacity guarantees for a specific VPS.
Choose workers and memory limits from the release’s deployment guidance and measured workload, including PostgreSQL and cron. Twice four cores plus one is nine, not five; an illustrative formula does not replace load testing or establish RAM per user.
| 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 | Inspect Odoo 18 /websocket routing, worker mode and evented-service logs |
| Permission denied writing filestore | Files owned by root after a manual copy | Inspect the actual data_dir and ownership; correct only identified paths, not an indiscriminate recursive ownership change |
| Database creation fails from the UI | The PostgreSQL role is not a superuser | Check the dedicated role’s intended CREATEDB privilege during provisioning; Odoo’s role must not be a superuser |
Odoo hosting from WebJi
Confirm Odoo hosting, application care, backup and certificate responsibilities in the written service scope. Odoo hosting is the matching service to discuss supported installation and ongoing care. Confirm database, proxy, certificates, addons and backup responsibilities in writing rather than assuming every item is included in a generic server price.
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.
Use a coordinated files-and-database backup procedure for recovery planning, and check certificate renewal separately from whether the Odoo service starts.
Frequently asked questions
Can Odoo run on a 2 GB VPS?
A small trial may fit a small VPS, but no tested user or worker capacity is established here. Plan Odoo, PostgreSQL, filestore and backup load together. Measure representative tasks before choosing resources for a production team rather than treating a RAM number as a guarantee.
Which Ubuntu version should I use for Odoo?
Choose a supported Ubuntu release compatible with the pinned Odoo branch and its dependencies. The Odoo 18 example needs Python 3.10 or later and PostgreSQL 12 or later. Verify the renderer package, Python requirements and system dependencies for the actual architecture.
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?
Use the pinned release’s official deployment guidance and measure your actual modules, concurrency and memory usage. A CPU heuristic is not a measured user limit. Include cron, PostgreSQL and the evented service in the resource budget, then verify performance and worker recycling under representative load.
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.
Last editorial update: 14 November 2026.
Ready to get started with WebJi®?
Join 12,000+ businesses across India and overseas. INR pricing, 18% GST shown before payment and 24/7 email support in Hindi and English — average first reply under 60 minutes.