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 →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
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
To self-host Odoo with Nginx, keep Odoo’s application server on a private address such as 127.0.0.1:8069, let Nginx own the public web ports, and use Nginx as the reverse proxy. Port 80 should redirect every request to HTTPS; authenticated Odoo traffic should not remain on cleartext HTTP.
The working pattern is Nginx on ports 80 and 443, Odoo on its internal HTTP port, PostgreSQL reachable only where Odoo needs it, and a separate Nginx route for the realtime worker used by your Odoo release. Odoo must have proxy mode enabled, and Nginx must pass the original host, client address, and protocol.
PC 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 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWhat “run Odoo on port 80” actually means
Odoo does not need to bind directly to port 80. In a production deployment, Nginx listens publicly on port 80 and receives requests for your hostname. Its port-80 server immediately redirects those requests to the HTTPS endpoint. Nginx also listens on port 443, terminates TLS, and forwards the request to Odoo’s private listener, commonly 127.0.0.1:8069.
This separation prevents the Odoo process from requiring privileged port access and keeps its application port off the internet. It also gives you one place to enforce TLS, request headers, connection limits, logging, and firewall policy.
#1 Best Overall
The request path
- A browser requests
http://odoo.example.comon port 80. - Nginx returns a permanent redirect to the HTTPS URL.
- The browser reconnects to
https://odoo.example.comon port 443. - Nginx terminates TLS and proxies ordinary Odoo requests to
127.0.0.1:8069. - For long-polling or websocket traffic, Nginx sends the matching realtime path to the gevent or LiveChat worker required by the installed Odoo release.
- Odoo sees the original public host, protocol, and client address through the forwarded headers.
Odoo’s deployment guidance states that a secure deployment must use HTTPS. Enable proxy mode only when every public request reaches Odoo through a trusted reverse proxy; enabling it while exposing Odoo directly can let clients forge proxy headers.
Prerequisites and a sensible deployment layout
Host requirements
- A supported Linux server with enough CPU, memory, and disk I/O for Odoo, PostgreSQL, scheduled jobs, and installed modules.
- A DNS name pointed at the server’s public address.
- Odoo and PostgreSQL installed on the same host or on a private network that is not exposed unnecessarily to the internet.
- Nginx installed and able to bind ports 80 and 443.
- A TLS certificate and private key for the hostname.
- Administrative access to validate and reload services, inspect logs, and configure the firewall.
Keep the internal services private
Bind Odoo’s HTTP listener to localhost or an internal interface. The common upstream address is 127.0.0.1:8069. Do not publish that port in your firewall or cloud security group when Nginx runs on the same host. PostgreSQL should likewise accept connections only from the addresses Odoo actually uses.
Plan workers from the workload, not from a slogan
Odoo’s multiprocessing server is intended for production on Linux. The official planning heuristic is (number of CPUs × 2) + 1 workers. Odoo also gives an approximate planning figure of six concurrent users per worker. These are starting points, not guarantees: installed modules, report generation, database queries, cron activity, imports, and hardware can change the result.
| Planning item | Official figure or rule | How to use it |
|---|---|---|
| Worker count | (CPU × 2) + 1 |
Use as an initial value, then observe CPU, memory, queueing, and response times. |
| Concurrent users | Approximately 6 users per worker | Treat this as an estimate for capacity planning, not a service-level promise. |
| Heavy worker memory | About 1 GB RAM under Odoo’s stated assumptions | Reserve headroom for the operating system, PostgreSQL, Nginx, cron jobs, and bursts. |
| Light worker memory | About 150 MB RAM under Odoo’s stated assumptions | Do not multiply this figure blindly; module mix and request type determine actual use. |
Set a nonzero workers value for production and configure Odoo’s memory, CPU, request, and real-time limits for the server. Monitor before increasing workers: adding processes on a memory-constrained host can cause swapping or out-of-memory kills instead of improving throughput.
Install Odoo and PostgreSQL before adding the proxy
Install Odoo and PostgreSQL using packages or the installation method appropriate for your Linux distribution and the Odoo release you selected. Keep the Odoo service running on its private HTTP port first. Before involving Nginx, verify locally that Odoo can connect to PostgreSQL, complete database initialization, serve the login page, load static assets, and execute a basic request.
Rank #2
Confirm the internal listener
Check the Odoo configuration or service arguments for the HTTP interface and port. A typical private listener is:
Free tools Windows power users keep installed
One-click scans. No signup required.
[options]
http_interface = 127.0.0.1
http_port = 8069
workers = 3
proxy_mode = True
The worker number above is only an example. Replace it with a value derived from your CPU and memory budget, then tune it after observing real workload. If your package uses command-line options instead of a configuration file, the equivalent proxy setting is --proxy-mode.
Enable proxy mode carefully
Set proxy_mode = True only after Nginx is the trusted entry point for all public Odoo requests. In proxy mode, Odoo relies on headers such as X-Forwarded-Proto and X-Forwarded-Host to determine the URL and scheme a user actually requested. If users can reach Odoo directly, they may be able to supply misleading values.
Create the Nginx server blocks
Use a dedicated Nginx configuration for the Odoo hostname. The following pattern shows the important structure. Substitute your real hostname and certificate paths; the internal Odoo port and realtime port must match your installation.
Define private upstreams and websocket handling
upstream odoo_http {
server 127.0.0.1:8069;
}
upstream odoo_realtime {
server 127.0.0.1:8072;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
Older Odoo examples use port 8072 for the long-polling worker. Newer releases describe routing websocket paths to the gevent worker and its port. Do not assume that a path from one release applies to another: use the realtime path and port documented for the exact Odoo version you installed.
Rank #3
Make port 80 redirect to HTTPS
server {
listen 80;
server_name odoo.example.com;
return 301 https://$host$request_uri;
}
This server intentionally does not proxy authenticated sessions over HTTP. A redirect preserves the requested path and query string while moving the browser to the encrypted endpoint.
Proxy ordinary requests from the TLS server
server {
listen 443 ssl;
server_name odoo.example.com;
ssl_certificate /etc/ssl/odoo/odoo.example.com.crt;
ssl_certificate_key /etc/ssl/odoo/odoo.example.com.key;
location / {
proxy_pass http://odoo_http;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_read_timeout 600s;
proxy_connect_timeout 600s;
proxy_send_timeout 600s;
}
}
The four forwarded headers are significant. X-Forwarded-Host preserves the public hostname, X-Forwarded-For carries the client chain, X-Forwarded-Proto tells Odoo that the browser used HTTPS, and X-Real-IP supplies the immediate client address. The longer proxy timeouts prevent Nginx from terminating legitimate reports, imports, or other slow Odoo requests prematurely. Size them for your workload and keep them consistent with Odoo’s own request and real-time limits.
Add the release-specific realtime location
If your release uses the older long-polling endpoint, place this location before the general / block:
location /longpolling {
proxy_pass http://odoo_realtime;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
}
For an Odoo release that uses websockets, replace the path with that release’s documented websocket path and retain the upgrade headers:
location /websocket {
proxy_pass http://odoo_realtime;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
}
The /websocket example is a pattern, not a claim that every release uses that literal path. Keep only the location required by your installed version, and point it at the gevent or LiveChat worker port configured for that release. Routing the wrong path to the ordinary HTTP worker is a common reason Discuss, Live Chat, or notification updates appear frozen.
Rank #4
Validate and activate the configuration
- Save the server block in the location used by your distribution and enable it for Nginx.
- Run
nginx -t. Do not reload until the syntax test reports success. - Reload Nginx with your service manager so existing connections are handled gracefully.
- Confirm that the certificate and key are readable by the Nginx worker and that the hostname resolves to this server.
- From a separate machine, request the HTTP URL and verify a redirect to the HTTPS URL.
- Open the HTTPS URL, log in, load an app, and check that static assets and browser requests return successfully.
A successful syntax test proves only that Nginx can parse the file. It does not prove that Odoo is listening, that PostgreSQL is healthy, that the certificate matches the hostname, or that the realtime endpoint is correctly routed.
Test the parts users actually depend on
Basic HTTP and authentication
- HTTP port 80 returns a redirect rather than an Odoo login page.
- HTTPS loads without a certificate or mixed-content warning.
- The login form submits successfully and the browser remains on the HTTPS hostname.
- Assets, images, attachments, and downloads use the expected public URL.
Long-running requests
- Run a report or import that takes longer than a normal page request.
- Watch Nginx and Odoo logs while it runs.
- If Nginx closes the connection first, increase its read, connect, and send timeouts within a limit that still protects the server, then check Odoo’s own request limits.
Discuss, Live Chat, and notifications
- Open Discuss in two browser sessions and send a message.
- Test Live Chat if it is enabled.
- Use browser developer tools to see whether the long-polling or websocket request remains connected and whether it returns a 4xx or 5xx response.
- Verify that the realtime path is routed to the gevent or LiveChat worker rather than the normal
8069upstream.
Troubleshooting by symptom
502 Bad Gateway
Nginx cannot reach the upstream. Confirm that the Odoo service is running, that it is listening on the address and port in the upstream block, and that local firewall rules do not block the connection. If Odoo is bound only to an internal address other than localhost, change the upstream to that address and keep it private.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Redirect loops or incorrect HTTP URLs
Check that Odoo proxy mode is enabled and that Nginx sends X-Forwarded-Proto $scheme and X-Forwarded-Host $host. A missing or incorrect protocol header can make Odoo believe the original request was HTTP and generate redirects back to the wrong scheme.
Login succeeds, then the session fails
Confirm that the public hostname in the browser matches the hostname in the certificate and Nginx server_name. Check forwarded host and protocol headers, cookie warnings, and whether a second proxy or load balancer is rewriting them. Do not enable proxy mode while allowing users to bypass Nginx.
Assets are missing or pages look unstyled
Inspect the failed asset requests in the browser and compare their scheme and hostname with the page URL. Incorrect forwarded headers, a certificate mismatch, or a location rule that catches asset paths unexpectedly can produce mixed-content or failed-resource errors. Review both Nginx and Odoo logs for the exact path and status.
Best Value
Chat or notifications never update
This usually indicates a realtime routing problem rather than a normal page-proxy problem. Check the installed Odoo release’s required path, the gevent or LiveChat worker port, and the corresponding Nginx location. For websocket traffic, ensure Upgrade, Connection, and HTTP/1.1 are present. For older long-polling deployments, route /longpolling to the documented worker port.
Long reports time out
Compare the Nginx read, connect, and send timeouts with Odoo’s CPU and real-time limits. Raising only Nginx’s timeout cannot rescue a request that Odoo terminates internally. Also check worker saturation, database locks, memory pressure, and slow module code.
Firewall, database, and backup controls
Expose only the public edge
Allow inbound web traffic to Nginx as required by your TLS and redirect design. Keep PostgreSQL, Odoo’s 8069 HTTP port, and the realtime worker port inaccessible from the public internet unless a specific multi-host architecture requires private-network access. Restrict administrative ports to trusted addresses and review cloud security-group rules as well as the host firewall.
Back up both database and filestore
An Odoo recovery plan needs an off-host copy of the PostgreSQL databases and the Odoo filestore. Test restoration on a separate environment rather than assuming that a completed backup job is recoverable. Retain credentials and encryption keys needed to use the backups, and monitor backup age and available storage.
Watch logs and capacity
Monitor Nginx access and error logs, Odoo service logs, PostgreSQL health, worker memory, CPU, disk space, and response times. A worker count that works during ordinary browsing may fail during imports, scheduled jobs, or reporting. Use observed concurrency and memory consumption to tune workers and limits instead of treating the planning heuristics as fixed guarantees.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteChoosing a host for self-hosted Odoo
Compare infrastructure on the constraints that affect Odoo, not only on advertised CPU counts. Check:
- CPU and RAM headroom for Odoo workers, PostgreSQL, scheduled jobs, and bursts.
- Disk I/O performance and durable storage for database and filestore activity.
- Backup and restore controls, including off-host or object-storage targets.
- Geographic region and network latency for your users and integrations.
- Firewall and private-network features for PostgreSQL and internal Odoo ports.
- TLS automation and certificate renewal support.
- Monitoring, alerting, and access to service and kernel logs.
- Whether the host permits the PostgreSQL version, worker count, background jobs, and operating-system configuration your Odoo release needs.
A repeatable operating checklist
- Keep DNS pointed at the Nginx host and confirm the certificate covers the exact public hostname.
- Keep Odoo’s application and realtime ports private.
- Set a nonzero production worker count and resource limits appropriate to the host.
- Enable
proxy_modeonly behind the trusted proxy. - Use port 80 only for the HTTP-to-HTTPS redirect.
- Proxy ordinary requests to the Odoo HTTP upstream and pass all required forwarded headers.
- Configure the version-correct long-polling or websocket location.
- Run
nginx -tbefore every reload. - Test login, assets, attachments, long requests, Discuss, Live Chat, and notifications after changes.
- Review logs and capacity metrics, keep PostgreSQL and internal ports firewalled, and verify off-host database and filestore backups.
With this layout, Nginx owns the public web interface and port 80 redirect, HTTPS protects Odoo sessions, and Odoo remains isolated on a private service port. The only release-specific part you must resolve before going live is the realtime path and worker port used by your installed Odoo version.
Quick Recap
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.

