Skip to main content

Setting up an nginx reverse proxy

Setting up an nginx reverse proxy

While Odoo itself can serve web pages, it's strongly recommended that there is a reverse proxy positioned in front of it. A reverse proxy acts as an intermediary that manages the traffic between clients sending requests and the Odoo servers responding to them. Using a reverse proxy has several benefits.
On the security side, it can do the following:
  • Handle (and enforce) HTTPS protocols to encrypt traffic
  • Hide the internal network characteristics
  • Act as an application firewall, limiting the URLs accepted for processing
Also, on the performance side, it can provide the following significant improvements:
  • Cached static content, hence reducing the load on the Odoo servers
  • Compressed content to speed up loading time
  • Act as a load balancer, distributing load between several servers
Apache is a popular choice when considering a reverse proxy, although nginx is a recent alternative with good technical arguments. Here, we'll choose to use nginx as a reverse proxy and show you how it can be used to perform the security and performance-side functions we've discussed.
First, we should install nginx. We want it to listen on the default HTTP ports, so we should ensure they aren't already taken by another service. Performing this command should result in an error, as follows:
$ curl http://localhost
curl: (7) Failed to connect to localhost port 80: Connection refused






If an error is not received, you should disable or remove the service to allow nginx to use those ports. For example, to stop an existing Apache server, use sudo service apache2 stop.
Better yet is the option of removing it from your system or reconfiguring it to listen on another port, so that the HTTP and HTTPS ports (80 and 443) are free to be used by nginx.
Once this process is complete, we can install nginx, which is done as follows:
$ sudo apt-get install nginx
$ sudo service nginx start  # start nginx, if not already started
To confirm that nginx is working correctly, we should see a Welcome to nginx page when visiting the server address with a browser or using curl http://localhost inside our server.
The nginx configuration files follow the same approach as Apache's—they are stored in /etc/nginx/available-sites/ and are activated by adding a symbolic link in /etc/nginx/enabled-sites/. Note that you should also disable the default configuration provided by the nginx installation, as follows:
$ sudo rm /etc/nginx/sites-enabled/default
$ sudo touch /etc/nginx/sites-available/odoo
$ sudo ln -s /etc/nginx/sites-available/odoo \
/etc/nginx/sites-enabled/odoo
Using an editor such as nano or vi, edit the nginx configuration file as follows:
$ sudo nano /etc/nginx/sites-available/odoo
A basic nginx configuration file for an Odoo server looks like the following example:
upstream odoo { 
  server 127.0.0.1:8069; 
} 
upstream odoochat { 
  server 127.0.0.1:8072; 
} 
server { 
  listen 80;

  # Add Headers for odoo proxy mode
  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;

  # log
  access_log /var/log/nginx/odoo.access.log;
  error_log /var/log/nginx/odoo.error.log;
  # Redirect longpoll requests to odoo longpolling port
  location /longpolling {
    proxy_pass http://odoochat;
  }
  # Redirect requests to odoo backend server
  location / {
    proxy_redirect off;
    proxy_pass http://odoo;
  }

 # common gzip
 gzip_types text/css text/scss text/plain text/xml application/xml application/json application/javascript;
 gzip on;
} 
First, we add upstream configuration sections for the Odoo services, listening at the default ports, 8069 and 8072. The 8069 port serves the web client and RPC requests, and 8072 serves the long polling requests used to support Odoo instant messaging features when using multiprocessing workers.
The nginx should receive traffic on the default HTTP port, 80, and redirect it to the upstream odooservices. This is defined in the server configuration section. Traffic for the /longpolling address is passed on to upstream odoochat, and the remaining traffic is passed on to upstream odoo.
Here, we also add some information to the request header that will let the Odoo backend service know that it's being proxied.
For security reasons, it's important for Odoo to ensure that the proxy_mode parameter is set to True. The reason for this is that when nginx acts as a proxy, all requests will appear to come from the server itself instead of the remote IP address; setting the X-Forwarded-For header in the proxy and enabling --proxy-mode solves that. However, enabling --proxy-mode without forcing the header at proxy-level will allow anyone to spoof their remote address.
At the end of the configuration file, we can see a couple of gzip-related instructions. These enable the compression of some files, improving performance.


To test whether the edited configuration is correct, use the following command:
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
If you find errors, verify that the configuration file is correctly typed. A common problem is for the default HTTP to be taken by another service, such as Apache or the default nginx website, so double-check the instructions given to ensure that this is not the case before restarting nginx. After this process is complete, nginx can reload the new configuration, as follows:
$ sudo /etc/init.d/nginx reload
If your operating system is using systemd, the appropriate version for the preceding command is as follows:
$ sudo systemctl reload nginx
We can now confirm that nginx is redirecting traffic to the backend Odoo server, as follows:
$ curl http://localhost
<html><head><script>window.location = '/web' +  location.hash;</script></head></html>

Comments

  1. Thank you, this blog is awesome and super. I really love your article. Thanks once again,
    Switzerland VPS Hosting

    ReplyDelete
  2. What an awesome written by you! I am too glad to read this kind of informative blog article. Thanks to sharing this with us, really thank you!!!!!!
    Dubai VPS Server

    ReplyDelete
  3. Please help with this eror mesage i am getting when i try to restart the nginx.

    nginx: [emerg] duplicate upstream "odoo" in /etc/nginx/sites-enabled/odoo.lotusb etaanalytics.com.conf.save:36

    ReplyDelete
  4. Please help with this error message i get when i try to restart the nginx.

    nginx: [emerg] duplicate upstream "odoo" in /etc/nginx/sites-enabled/odoo.lotusb etaanalytics.com.conf.save:36

    ReplyDelete

Post a Comment

Popular posts from this blog

The message and activity features

The message and activity features Odoo has available global  messaging  and activity planning features, provided by the  Discuss  application, with technical name mail. The mail module provides the  mail.thread  abstract class that makes it simple to add the messaging features to any model, and the  mail.activity.mixin  that adds planned activity features. This was done in  Chapter 4 ,  Extending Modules , to explain how to inherit features from mixin abstract classes. To add these features, we need to add the mail dependency to the add-on module,  library_checkout , and then have the library checkout model class inherit from the abstract classes providing the following features. Edit the  'depends'  key in the  library_checkout/__manifest__.py   file, to add the mail module, shown as follows: Copy 'depends': ['library_member' , 'mail' ], And edit the  library_checkout/m...

The QWeb template language

The QWeb template language The  QWeb  parser looks for special directives in the templates and replaces them with dynamically generated HTML. These directives are XML element attributes and can be used in any valid tag or element, such as  <div> ,  <span> , or  <field> . Sometimes, we may want to use a QWeb directive but we don't want to place it in any of the XML elements in our template. For those cases, we have a  <t>  special element that can have QWeb directives, such as  t-if  or  t-foreach , but is silent and won't have any output on the final XML/HTML produced. The QWeb directives will frequently make use of evaluated expressions to produce different results, depending on the current record values. There are two different QWeb implementations: client-side JavaScript and server-side Python. The reports and website pages use the server-side Python implementation of QWeb. Kanban views us...