iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
The most reliable production setup is Odoo 18 Community from Odoo’s signed Debian repository on Ubuntu 22.04 LTS or newer, or Debian Bookworm 12, with PostgreSQL on the VPS and Nginx terminating HTTPS in front of Odoo. Install the Odoo 18-compatible wkhtmltopdf 0.12.6 build separately, set a strong database-management password, and verify reports, WebSockets, services, and backups before exposing the server publicly.
Choose the Odoo release before you install anything
Odoo commands and dependencies are tied to the major release. Repository paths, supported operating systems, Python requirements, PostgreSQL versions, configuration defaults, and wkhtmltopdf builds can change between releases. The procedure below uses Odoo 18 documentation as its concrete reference. Check the matching official documentation if you intend to install another release; do not reuse an Odoo 18 repository entry or dependency set for Odoo 17, 19, or a development branch.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11For Odoo 18 packaged installation, Odoo documents support for Debian Bookworm 12 and Ubuntu Jammy 22.04 LTS or newer. Start with a fresh VPS running one of those distributions, a sudo-capable account, DNS for the hostname you will publish, and a firewall or cloud security group that permits SSH. Allow HTTP and HTTPS only when the reverse proxy is ready.
Package or source: which installation is right for your VPS?
| Consideration | Official Debian package | Source checkout |
|---|---|---|
| Best use | One conventional production instance | Module development, custom patches, or several Odoo versions |
| Operating-system alignment | Uses the release’s supported Debian/Ubuntu package repository | You must align the checkout, Python environment, system libraries, and PostgreSQL yourself |
| Service management | Installs an Odoo service and starts it automatically | You create and maintain the service unit |
| Dependencies | APT resolves package dependencies | setup/debinstall.sh and the release’s requirements.txt must be kept consistent |
| Upgrades and rollback | Package updates are simpler; retain database, filestore, and configuration backups before upgrading | You control the checkout and can pin versions, but upgrades and rollback require disciplined deployment steps |
| Side-by-side versions | Not the convenient option | Separate users, virtual environments, ports, configuration files, and service units can run different versions |
Choose the package unless you have a clear reason to control the source tree. Odoo’s source-installation guidance warns that careless pip-based dependency installation can create security and dependency problems; an isolated environment and a tested deployment process are essential.
#1 Best Overall
Prepare the Linux VPS
Minimum preparation checklist
- Ubuntu 22.04 LTS or newer, or Debian Bookworm 12, for the Odoo 18 package.
- A sudo-capable administrative account; avoid operating the application as root.
- A DNS record pointing the intended hostname to the VPS address.
- SSH access restricted to the addresses or keys you actually use.
- Firewall rules for SSH and, after the proxy is configured, TCP 80 and 443. Do not publish Odoo’s internal HTTP listener directly.
- A backup destination separate from the VPS for PostgreSQL dumps and the Odoo filestore.
Update the operating system
Connect over SSH and apply security updates before adding application repositories:
sudo apt update
sudo apt full-upgrade -y
sudo reboot
Reconnect after the reboot. Keep the system’s time, hostname, and DNS resolution working; incorrect time can cause certificate and scheduled-job problems.
Install Odoo 18 from the official Debian package
1. Install PostgreSQL
Odoo’s own documentation states, “Odoo needs a PostgreSQL server to run properly.” Install PostgreSQL from the distribution packages unless your architecture deliberately uses a managed or remote PostgreSQL server:
sudo apt install -y postgresql postgresql-client
For a local packaged installation, PostgreSQL normally listens on the local Unix socket and loopback interface. The Odoo package creates the application database role as part of its setup. Confirm that PostgreSQL starts before continuing:
sudo systemctl enable --now postgresql
sudo systemctl is-active postgresql
2. Add the Odoo 18 repository
Use the signed keyring and repository stanza shown in the Odoo 18 packaged-installation documentation. Copy the stanza exactly for the selected release and distribution; do not substitute a repository path from a different major version, an unsigned key, or an unofficial mirror. After adding it, refresh APT:
sudo apt update
This deliberate step matters because the package repository supplies the release-aligned Odoo build and its service integration. If you prefer a downloaded Community or Enterprise Debian package instead, skip the repository installation and use the procedure below.
3. Install the Odoo package
sudo apt install -y odoo
sudo systemctl enable --now odoo
sudo systemctl status odoo --no-pager
The package installs Odoo as a service, creates the required PostgreSQL user, and starts the server. A default installation commonly writes its configuration to /etc/odoo.conf, although you should confirm the path in the installed service unit and package files rather than assuming it.
4. Installing a downloaded .deb instead
If you obtained a matching Community or Enterprise package, install it with dpkg, repair any missing dependencies with APT, and run dpkg again:
Rank #2
sudo dpkg -i ./odoo_18.*.deb
sudo apt-get install -f -y
sudo dpkg -i ./odoo_18.*.deb
Enterprise package downloads require an eligible paid on-premise customer or partner login. Keep the package’s release and architecture aligned with the VPS; do not mix files from different Odoo majors.
Install wkhtmltopdf for usable PDF reports
Odoo 18 specifies wkhtmltopdf version 0.12.6 for report headers and footers and explicitly notes that pip does not install it. Obtain the Odoo-compatible 0.12.6 build for your operating system from the release documentation, install it separately, and verify that the executable is on the service user’s PATH:
wkhtmltopdf --version
The command should report the intended 0.12.6 build. A distribution package with a different version, a binary compiled without the required patched Qt features, or an executable unavailable to the Odoo service can produce blank PDFs or missing headers and footers. Test an invoice or another report after configuring the application, not just the command-line version.
Configure Odoo and PostgreSQL securely
Set the database-management password
Edit the configuration file used by the service and set a long, random admin_passwd. This value protects database-management operations in the Odoo web interface; it is not the same thing as an ordinary user’s Odoo login password:
sudoedit /etc/odoo.conf
admin_passwd = replace-with-a-long-random-secret
Protect the file from unprivileged users and restart Odoo after changes:
sudo chown root:odoo /etc/odoo.conf
sudo chmod 640 /etc/odoo.conf
sudo systemctl restart odoo
Use a PostgreSQL role that is not a superuser. Database ownership and the application login should be separated according to Odoo’s deployment guidance. Never configure Odoo to connect as PostgreSQL’s postgres superuser.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
When PostgreSQL is on another host
A remote database requires intentional network and authentication configuration. Configure PostgreSQL to listen on the required private address, add a narrowly scoped rule in pg_hba.conf, restrict the database port with the firewall, and prefer encrypted connections. Set Odoo’s database host, port, user, password, and SSL options in its configuration. Do not open PostgreSQL to the entire internet.
Useful configuration areas
- Database options: Set the host and port only when they differ from the local defaults; use a dedicated non-superuser role.
addons_path: Include the core addons directory and any controlled custom-addons directory. Keep custom code outside the packaged files so upgrades do not overwrite it.- Log location: Choose a location that the service user can write and rotate. During initial setup, the system journal is also valuable.
- Resource limits: Add worker, request-time, and memory limits only after considering the VPS’s CPU, RAM, installed modules, and concurrent users.
Install Odoo from source when you need development control
1. Create a dedicated PostgreSQL role
Odoo’s source-installation documentation supports PostgreSQL 12.0 or above and forbids connecting as the postgres superuser. Create a login role with only the database privileges your deployment needs; CREATEDB is commonly required when Odoo must create databases:
Rank #3
sudo -u postgres psql -c "CREATE ROLE odoo LOGIN CREATEDB NOSUPERUSER NOCREATEROLE;"
Set a password only if your chosen authentication method requires one, and store it outside shell history. If you will create databases exclusively through an administrator-controlled process, remove unnecessary privileges after validating the workflow.
2. Obtain the matching source and isolate Python
Download or check out the exact Odoo Community branch or release archive you intend to run. Keep it in a dedicated directory such as /opt/odoo, and use a virtual environment for that release so another application cannot alter its Python packages:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →sudo mkdir -p /opt/odoo
sudo chown -R $USER:$USER /opt/odoo
cd /opt/odoo
python3 -m venv venv
. venv/bin/activate
The Python interpreter version must be the one supported by your selected Odoo release. Do not infer it from a different major version.
3. Install system and Python dependencies
From the Odoo source tree, run the release-provided Debian dependency script:
sudo ./setup/debinstall.sh
If you install dependencies manually, install the documented system libraries first and then use that release’s requirements.txt inside the virtual environment:
. /opt/odoo/venv/bin/activate
pip install --upgrade pip
pip install -r /opt/odoo/requirements.txt
Review every package change before applying it. A blind global pip install can replace distribution libraries, create incompatible versions, or introduce security exposure.
4. Add a system user and service
Run Odoo under a dedicated, non-login system account and give it ownership only of the source, filestore, custom-addons, log, and configuration paths it needs:
sudo useradd --system --home /opt/odoo --shell /usr/sbin/nologin odoo
sudo chown -R odoo:odoo /opt/odoo
Create a systemd unit that points to the release’s virtual-environment interpreter and configuration file. A minimal pattern is:
Rank #4
[Unit]
Description=Odoo application
After=network.target postgresql.service
[Service]
Type=simple
User=odoo
Group=odoo
ExecStart=/opt/odoo/venv/bin/python /opt/odoo/odoo-bin -c /etc/odoo/odoo.conf
Restart=on-failure
[Install]
WantedBy=multi-user.target
Save it as /etc/systemd/system/odoo.service, then enable and inspect it:
sudo systemctl daemon-reload
sudo systemctl enable --now odoo
sudo systemctl status odoo --no-pager
Keep the source checkout, configuration, custom-addons path, filestore, and service unit organized separately. That layout makes it possible to test a new checkout and roll back without deleting the live filestore or database.
Put Odoo behind Nginx and HTTPS
Odoo’s development HTTP listener should not be your public endpoint. Use Nginx, Apache, or another reverse proxy to terminate HTTPS, then forward requests to Odoo over the private loopback interface. Odoo’s documentation states: “The proxy mode option must be enabled when Odoo is behind a reverse proxy.” Set proxy_mode = True in the Odoo configuration.
Configure the proxy headers
The proxy must preserve the original host, scheme, and client address. An Nginx server block can follow this pattern after you substitute your hostname and certificate paths:
server {
listen 80;
server_name odoo.example.test;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name odoo.example.test;
ssl_certificate /etc/ssl/odoo/fullchain.pem;
ssl_certificate_key /etc/ssl/odoo/privkey.pem;
client_max_body_size 200m;
location /websocket/ {
proxy_pass http://127.0.0.1:8072;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
proxy_pass http://127.0.0.1:8069;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 720s;
}
}
The port in the /websocket/ block must match the gevent or LiveChat worker port configured for your Odoo instance. The example uses 8072; change it if your configuration uses another value. When Odoo runs in multi-process mode, a dedicated LiveChat worker listens on that gevent port. Omitting this route can make discuss, notifications, and other real-time features fail even while ordinary pages load.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesIssue and test the certificate
Use your distribution’s supported certificate-issuance method, ensure the DNS record resolves to the VPS, and configure automatic renewal. Validate the Nginx configuration before reloading:
sudo nginx -t
sudo systemctl reload nginx
Browse to the HTTPS hostname, confirm the certificate name and chain, and check that Odoo generates secure URLs rather than redirecting between HTTP and HTTPS.
Size workers and operate the services
Worker count, memory ceilings, request limits, and timeouts depend on CPU, RAM, installed modules, and concurrent users. Odoo’s documentation gives a theoretical maximum worker formula of (CPU threads × 2) + 1, but it is a sizing heuristic, not a universal setting. Validate it against observed load and memory rather than copying the maximum.
Best Value
| Documented example | Value | How to interpret it |
|---|---|---|
| CPU | 4 CPUs, 8 threads | Input to the example sizing calculation |
| Concurrent users | 60 | Illustrative workload, not a capacity guarantee |
| Odoo workers | 8 | Example application-worker setting |
| Cron workers | 1 | Separate scheduled-job worker in the example |
| Odoo memory | Approximately 3 GB | Example allocation; actual use varies by modules and workload |
Enable both services at boot and inspect them after every reboot:
Free tools Windows power users keep installed
One-click scans. No signup required.
sudo systemctl enable postgresql odoo
sudo systemctl is-active postgresql odoo
sudo journalctl -u odoo -n 100 --no-pager
Watch CPU, RAM, swap, disk space, PostgreSQL activity, request latency, and worker restarts. A VPS that appears adequate during installation can run out of memory during imports, report generation, module updates, or concurrent background jobs.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Verify the installation before production use
- Reboot test: Reboot the VPS and confirm that PostgreSQL, Odoo, and the reverse proxy return to an active state automatically.
- Hostname and TLS: Load the Odoo web interface through the real hostname over HTTPS; do not validate only by visiting the internal port.
- Database administration: Create a test database with the configured
admin_passwdand restricted PostgreSQL role, then remove the test database if it is not needed. - Application login: Create an administrator account with a unique password and verify that ordinary users cannot access database-management operations.
- PDF output: Export an invoice or another report and check the content, header, footer, fonts, and page breaks. This confirms that the installed wkhtmltopdf binary is usable by the Odoo service.
- Real-time features: If multi-process mode is enabled, test Discuss, notifications, or LiveChat while watching the proxy and Odoo logs for WebSocket upgrades.
- Backups: Take a PostgreSQL backup and copy the Odoo filestore, then perform a restore to a separate test location. A backup that has never been restored is not a verified recovery plan.
Common failures and targeted fixes
Odoo service will not start
Read the service journal and Odoo log first:
sudo systemctl status odoo --no-pager
sudo journalctl -u odoo -b --no-pager
Look for a malformed configuration line, a missing Python module, an inaccessible filestore or log directory, a port already in use, or a database authentication error. Correct ownership and permissions for the service user, then restart and recheck the journal rather than repeatedly rebooting.
Database connection or permission errors
Confirm that PostgreSQL is active, the configured role exists, the database host and port are correct, and pg_hba.conf permits only the intended source. A role that is accidentally a superuser defeats the security boundary; create a replacement role with the minimum required privileges and update Odoo’s configuration.
Blank PDFs or missing headers and footers
Check wkhtmltopdf --version as the Odoo service user, verify that it reports the Odoo 18-specified 0.12.6 build, and ensure the executable is on the service PATH. Restart Odoo after changing the binary or configuration and repeat an actual report export. Installing a Python package will not supply wkhtmltopdf.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →502 Bad Gateway from Nginx
A 502 generally means that Nginx cannot reach Odoo on the configured upstream. Confirm that Odoo is listening on the expected loopback port, that the service is active, and that the proxy’s proxy_pass value matches the configuration. Check Nginx’s error log and Odoo’s journal together to distinguish a stopped service from a rejected request.
Pages work but notifications or LiveChat do not
Verify that multi-process mode is enabled as intended, identify the actual gevent worker port, and route /websocket/ to that port with WebSocket upgrade headers. A route pointing at the normal HTTP worker will not provide the required real-time connection.
Upgrade broke a custom module
Stop the service, preserve the current source or package version, database dump, filestore, configuration, and custom-addons directory, and test the new Odoo release in a separate environment. Upgrade only after custom modules and dependencies are compatible. Rollback means restoring the matching application version together with the database and filestore; restoring only one of those components can leave the instance inconsistent.
Backups, updates, and ongoing maintenance
Back up both parts of an Odoo instance: PostgreSQL databases and the Odoo filestore. The database contains structured records, while the filestore contains uploaded documents and other attachments. Schedule backups to storage outside the VPS, retain multiple restore points, encrypt sensitive backups, and periodically perform a complete restore drill.
Apply Odoo updates through the package manager or the current, release-appropriate source build. Read the release notes, take a fresh backup, test custom modules, and monitor logs and resource use after the restart. Keep the operating system, PostgreSQL, Odoo, reverse proxy, and certificate-renewal process maintained as separate change areas so a problem can be isolated quickly.
Quick Recap
Final production checklist
- The selected Odoo major release, operating system, Python environment, PostgreSQL version, and wkhtmltopdf build are mutually supported.
- The Odoo service runs as a dedicated non-root user and PostgreSQL access does not use the
postgressuperuser. - A strong
admin_passwdis set and the configuration file is not world-readable. - Nginx or another proxy terminates HTTPS, sends the original host and scheme headers, and has
proxy_modeenabled in Odoo. - The
/websocket/route reaches the configured gevent worker when multi-process mode is enabled. - PostgreSQL and Odoo start after reboot, logs are monitored, and resource limits match observed workload.
- PDF reports show expected headers and footers.
- Backups include PostgreSQL and the filestore, and a documented restore has succeeded.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

