How to: Install Nginx as a reverse proxy for Apache2

Unravel The Music is a small startup; by that I mean we have no money, no financing, and we are owned and operated by two people. Therefore it is important that we get the most out of our server in terms of performance and cost and we have to do this without having to spend hours worrying about the server when we could be improving our design or code.

First off, without good hardware it's not going to matter how well your server is setup because you will be constantly worrying about whether your server is even up or if the datacenter is having another monthly outage. For this problem we recommend Linode. I'm sure there are plenty of other great VPS hosts out there but we have had a lot of luck with Linode and highly recommend them.

This how-to is going to assume that you already have a standard LAMP stack running, if not, there are plenty of tutorials and examples on how to get a LAMP stack running.

We have chosen to go with a standard Apache 2 installation using libapache2modphp5 over using Nginx (pronounced 'Engine X') with fastCGI. You may be thinking “that is preposterous, why not just use Nginx as your webserver and ditch Apache?” I hate fastCGI, I've never had very good luck with it and most importantly I know Apache. Also, when all Apache has to worry about is the dynamic content, in this case PHP, it is quite fast, and has a smaller memory footprint then normal Apache usage.

Using Nginx as a reverse proxy is great for a few reasons. Firstly it handles static content very well. It is able to handle the requests and serve static content much faster in our tests and this has cut our page load time in about half (using YSlow with a clear cache). The memory footprint of Nginx is very small so this extra speed increase is worth every megabyte, in this case .6 megabytes of our total ram on a 540 megabyte server. Secondly, it allows for quick and easy migration of your Apache services to another server. Through the config files you are able to specify an IP of your server and a port. If your apache server is taking a pounding it wouldn't be difficult to move it to another server and just change the proxy IP to your now remote server.

Setting up Nginx is fairly straight forward. I will be showing the commands for an Ubuntu 8.04 installation but they should work for previous versions and other distributions (with a little tweaking).

Install Nginx

sudo apt-get install nginx

the following is essentially the config file we use for /etc/nginx/nginx.conf and is pretty similar to the default config for the installation. The only major thing I changed was adding gzip compression. I have personally set the level to 5 although it is adjustable. The higher you set this value the more CPU intensive it becomes.

user www-data;
worker_processes  2;
error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    access_log /var/log/nginx/access.log;
server_names_hash_bucket_size 64; 
    sendfile        on;
    tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;
    tcp_nodelay        on;
    gzip              on;
  gzip_comp_level   5;
  gzip_http_version 1.0;
  gzip_min_length   0;
  gzip_types        text/plain text/html text/css image/x-icon 
    application/x-javascript;
  gzip_vary         on;
  include /etc/nginx/conf.d/*.conf;
  include /etc/nginx/sites-enabled/*;

You are going to want to make sure that the line “include /etc/nginx/conf.d/*.conf;” is included in this config. This is where you will store the default proxy information.

We will now configure the default proxy. Create the file proxy.conf in the /etc/nginx/conf.d/ folder with the following contents.

proxy_redirect          off;
proxy_set_header        Host            $host;
proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size    10m;
client_body_buffer_size 128k;
client_header_buffer_size 64k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffer_size   16k;
proxy_buffers       32   16k;
proxy_busy_buffers_size 64k;

The only thing you may want to change is the buffer sizes. We had to increase our proxybuffersize and a few others, from the default, to allow for larger cookies that were choking Nginx. With that being said you may want to decrease the buffers a bit, just do some testing. If the buffers are not working for your content Nginx will throw a 50x error.

Finally, we will configure the various hosts. To save yourself some time, and possible a headache you should always keep your static assets in one folder, while subdividing them by type in containing folders. For example static->images, static->js, static->css. This will greatly simplify your Nginx installation and I've found your code.

Now we will edit (with your favorite CLI editor) /etc/nginx/sites-available/default.

server {
 listen   80;
 server_name  example.com;
 access_log  /var/www/example.com/log/nginx.access.log;
 error_log  /var/www/example.com/log/nginx_error.log debug;

 #set your default location
 location / {
  proxy_pass         http://127.0.0.1:8080/;
 }

 #I had a problem accessing phpmyadmin with an Nginx reverse 
 #proxy without adding this location
 location /phpmyadmin {
  proxy_pass         http://127.0.0.1:8080/phpmyadmin;
  allow 1.1.1.1;
  deny all;
 }
 #set your static folder location without the proxy pass so Nginx 
 #will server those files. We also set expires max to add an
 #expires to have the client cache the files.  You will
 #have to  #set a version on your css and js files to prevent 
 #the user who has cached files from not receiving new versions.
 location /static {
  root   /var/www/example.com/htdocs/;
  expires     max;
  }
  #error_page  404  /404.html;
  # redirect server error pages to the static page /50x.html
 #
 error_page   500 502 503 504  /50x.html;
 location = /50x.html {
  root   /var/www/nginx-default;
 }
}
#If you have a subdomain you need to add a new server if you 
#want Nginx to server the static files. Our subdomain only 
#serves static files so we have not set up a proxy_pass 
server {
 listen 80;
 server_name subdomain.example.com;
 error_page 500 502 503 504 /50x.html;
 location = /50x.html {
  root /var/www/nginx-default;
 }
 access_log /var/www/subdomain.example.com/log/nginx.access.log;
 error_log /var/www/subdomain.example.com/log/nginx.error.log;
 index index.html;
 location / {
  expires     max;
  root /var/www/subdomain.example.com/htdocs/; 
 }
}

Finally we need to make some quick changes to Apache and we'll finally have everything running. Edit the file /etc/apache2/ports.conf.

You'll want to change the listen line to 127.0.0.1:8080. This will prevent apache from receiving requests from outside, but you should be blocking port 8080 anyways! The port we've set is 8080 but whatever you set in the Nginx configs is what you should use.

NameVirtualHost *
Listen 127.0.0.1:8080

Lastly, if you don't want all your apache logs to show 127.0.0.1 for who is accessing your files or your application uses IP's to track sessions you need to install libapache2modrpaf. It is painless just issue the command below.

sudo apt-get install libapache2-mod-rpaf

reload or restart both Apache2 and Nginx.

/etc/init.d/apache2 restart
/etc/init.d/nginx restart

To see if it is working open a page on your website, if you don't see any errors that is a good start. You can then check the logs of Apache and Nginx. Your Apache logs should only contain the php requests and your Nginx logs should contain all of your assets. Your Apache logs should also have HTTP 1.0 request when they go through the reverse proxy.

If you need any support just leave a comment and we'll try and help you.

Source

1 Reply

First thank you for this quality post.

I follow your instructions but im stuck at setting the

/etc/nginx/sites-available/default.

I rent one server just to be my ngnix proxy for my 3 sites. They are on another server. Can you help me?

When i try to start ngnix i get this error:

2010/02/12 09:52:36 [emerg] 14860#0: "location" directive is not allowed here in /etc/nginx/sites-enabled/default:10

Regards

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct