KSA | Bahrain | UAE | India

Nginx vs Apache for Odoo: Which Is Better for Odoo ERP?

Nginx vs Apache for Odoo: Which Is Better for Odoo ERP?
When deploying Odoo in a production environment, choosing the right reverse proxy is an important decision for performance, security, scalability, and reliability.

Two of the most commonly used web servers are Nginx and Apache.

For modern Odoo deployments, Nginx is generally the preferred choice, particularly when you need efficient handling of concurrent connections, HTTPS termination, static assets, and Odoo’s real-time communication.

In this guide, we’ll compare Nginx vs Apache for Odoo and look at a production-ready Nginx configuration.


Why Does Odoo Need a Reverse Proxy?

Odoo can technically be accessed directly through port 8069, but exposing Odoo directly to the internet isn’t the ideal production architecture.

A reverse proxy such as Nginx vs Apache sits between the user and Odoo:

User
  ↓
HTTPS :443
  ↓
Nginx / Apache
  ↓
Odoo :8069
  ↓
PostgreSQL

A reverse proxy provides several important benefits.

1. SSL/TLS Termination

The reverse proxy handles HTTPS connections and SSL certificates while forwarding requests internally to Odoo.

This makes it easier to manage:

  • SSL certificates
  • HTTPS redirects
  • TLS versions
  • Security headers

2. Better Traffic Management

The reverse proxy can control how incoming requests are handled before they reach Odoo.

This becomes especially useful when running Odoo with multiple workers or multiple application instances.

3. Static Asset Handling

Odoo serves JavaScript, CSS, images, and other assets. Caching and compression at the reverse-proxy layer can reduce unnecessary load on Odoo workers.

4. Long-Polling / Real-Time Communication

Odoo uses a separate service for real-time communication in worker-based deployments. Depending on the Odoo version and configuration, this commonly involves port 8072.

A correctly configured reverse proxy routes those requests separately.


Nginx vs Apache for Odoo

Feature Nginx Apache
Concurrent connections Excellent Good
Memory efficiency Excellent Good
Reverse proxy Excellent Excellent
SSL/TLS Excellent Excellent
Static files Excellent Excellent
Odoo deployment Excellent Good
Configuration simplicity Excellent Good
Modern cloud deployments Excellent Good
Real-time Odoo routing Excellent Good
Recommended for new Odoo deployments Yes Possible

Why Choose Nginx?

Nginx uses an asynchronous, event-driven architecture that allows it to handle a large number of concurrent connections efficiently.

For Odoo environments, this can be particularly useful when you have:

  • Multiple users
  • Large databases
  • Heavy web traffic
  • Multiple Odoo workers
  • Real-time notifications
  • Large file uploads
  • Multiple Odoo instances

Apache can also work perfectly well with Odoo, but for a new production deployment, Nginx is often the simpler and more efficient choice.


Production-Ready Nginx Configuration for Odoo

Below is an example configuration covering:

  • HTTPS
  • HTTP → HTTPS redirect
  • SSL/TLS
  • Odoo reverse proxy
  • Long-polling
  • Large uploads
  • Extended timeouts
  • Proxy buffers
  • Gzip compression
  • Static asset caching
  • Security headers
Important: Replace yourdomain.com with your actual domain and adjust the SSL certificate paths and Odoo ports according to your environment.

Step 1 — Define Odoo Upstreams

The first upstream points to the main Odoo service, while the second is used for real-time communication when your Odoo deployment is configured to use port 8072.

upstream odoo {
    server 127.0.0.1:8069;
}

upstream odoo-chat {
    server 127.0.0.1:8072;
}

Step 2 — Redirect HTTP to HTTPS

This automatically redirects visitors from HTTP to HTTPS.

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    return 301 https://$host$request_uri;
}

Step 3 — Configure the HTTPS Server

server {
    listen 443 ssl http2;
    server_name yourdomain.com www.yourdomain.com;

    # SSL Certificate paths
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

If you’re using Let’s Encrypt with Certbot, Certbot normally manages these certificate files for you.

Step 4 — Configure Logging

access_log /var/log/nginx/odoo.access.log;
error_log /var/log/nginx/odoo.error.log;

Keeping separate Odoo logs makes troubleshooting considerably easier.

sudo tail -f /var/log/nginx/odoo.error.log

sudo tail -f /var/log/nginx/odoo.access.log

Step 5 — Configure Production Timeouts

Odoo can generate large reports, process imports, upload attachments, and perform long-running operations.

proxy_read_timeout 720s;
proxy_connect_timeout 720s;
proxy_send_timeout 720s;

client_max_body_size 100M;

The client_max_body_size setting is particularly useful when users need to upload large files or backups.

Step 6 — Configure Proxy Buffers

proxy_buffers 16 64k;
proxy_buffer_size 128k;

These settings control how Nginx buffers responses received from Odoo.

Step 7 — Enable Gzip Compression

gzip on;

gzip_types
    text/css
    text/less
    text/plain
    text/xml
    application/xml
    application/json
    application/javascript;

gzip_min_length 1000;

gzip_proxied expired no-cache no-store private auth;

Compression can reduce the amount of data transferred between the server and the browser.

Step 8 — Configure Odoo Long-Polling

For deployments using Odoo’s long-polling service, route the appropriate requests to port 8072.

location /longpolling {
    proxy_pass http://odoo-chat;

    proxy_next_upstream error timeout invalid_header
        http_500 http_502 http_503;

    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 https;
}

This helps support Odoo features that depend on real-time communication, such as notifications and chat.

Note: The exact real-time route and worker configuration can vary by Odoo version and deployment architecture. Always verify the configuration against the Odoo version you’re running.

Step 9 — Configure Main Odoo Traffic

All other requests can be forwarded to the Odoo application running on port 8069.

location / {
    proxy_pass http://odoo;

    proxy_next_upstream error timeout invalid_header
        http_500 http_502 http_503;

    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 https;

    proxy_http_version 1.1;

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "";
}

The forwarded headers allow Odoo to understand information about the original client request and protocol.

Step 10 — Cache Odoo Static Assets

location ~* /web/static/ {
    proxy_cache_valid 200 60m;

    proxy_pass http://odoo;

    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_set_header Host $host;

    expires 86400s;

    add_header Cache-Control "public, no-transform";
}

This can help reduce unnecessary traffic between the browser, Nginx, and Odoo.

Step 11 — Add Security Headers

add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";

These headers provide additional browser-level security controls.


Complete Nginx Configuration for Odoo

If you want the complete configuration in one place, use the following:

upstream odoo {
    server 127.0.0.1:8069;
}

upstream odoo-chat {
    server 127.0.0.1:8072;
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com www.yourdomain.com;

    # SSL Certificate
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # Logging
    access_log /var/log/nginx/odoo.access.log;
    error_log /var/log/nginx/odoo.error.log;

    # Production timeout & size limits
    proxy_read_timeout 720s;
    proxy_connect_timeout 720s;
    proxy_send_timeout 720s;

    client_max_body_size 100M;

    # Proxy buffering
    proxy_buffers 16 64k;
    proxy_buffer_size 128k;

    # Gzip
    gzip on;

    gzip_types
        text/css
        text/less
        text/plain
        text/xml
        application/xml
        application/json
        application/javascript;

    gzip_min_length 1000;
    gzip_proxied expired no-cache no-store private auth;

    # Long-polling / real-time communication
    location /longpolling {
        proxy_pass http://odoo-chat;

        proxy_next_upstream error timeout invalid_header
            http_500 http_502 http_503;

        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 https;
    }

    # Main Odoo routing
    location / {
        proxy_pass http://odoo;

        proxy_next_upstream error timeout invalid_header
            http_500 http_502 http_503;

        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 https;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "";
    }

    # Static assets
    location ~* /web/static/ {
        proxy_cache_valid 200 60m;

        proxy_pass http://odoo;

        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;

        expires 86400s;

        add_header Cache-Control "public, no-transform";
    }

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
}

Nginx vs Apache: Final Verdict

🥇 Nginx

Choose Nginx when you want:

  • High concurrent connection handling
  • Efficient resource usage
  • Easy SSL management
  • Reverse proxy functionality
  • Odoo real-time routing
  • Static asset caching
  • A modern production architecture

🥈 Apache

Apache remains a capable choice and can absolutely be used with Odoo, especially when your infrastructure already relies heavily on Apache or its existing modules and configuration.

But if you’re starting from scratch, Nginx is usually the more straightforward choice for an Odoo production stack.


Recommended Odoo Production Architecture

                    INTERNET
                        │
                        ▼
                 ┌─────────────┐
                 │    Nginx    │
                 │   HTTPS     │
                 │   :443      │
                 └──────┬──────┘
                        │
             ┌──────────┴──────────┐
             │                     │
             ▼                     ▼
       Odoo Workers          Real-Time Service
          :8069                  :8072
             │                     │
             └──────────┬──────────┘
                        ▼
                 ┌─────────────┐
                 │ PostgreSQL  │
                 └─────────────┘

This architecture provides a clean separation between the public-facing web layer and the Odoo application layer.

Conclusion

Nginx vs Apache isn’t really about whether Apache can run Odoo—it can.

The more important question is which architecture gives you the best combination of performance, security, maintainability, and scalability for your Odoo deployment.

For most new Odoo production environments, Nginx + Odoo + PostgreSQL is a strong and practical starting point.

Looking for Professional Odoo Implementation?

Need help with Odoo deployment, server configuration, customization, migration, or production optimization?

Get professional Odoo ERP implementation and support for your business.