Typical Configurations Overview For Nginx HTTP(S) Reverse Proxy/Web Server

Posted by Oleksiy Kovyrin under Networks · русский

In one of my previous posts I have described very powerful Unix admin tool – Nginx. As I said, main problem of this server is lack of English documentation. That is why I decided to write this post with list of typical nginx configurations and example configuration snippets for these configurations.

All sample configuration files are tested on up to date version of nginx, which has been compiled and installed with following commands:

1
2
3
 # ./configure --prefix=/usr/local/nginx --with-http_ssl_module
 # make
 # make install

So, you can simply download my sample, rename it to nginx.conf and adjust listening/proxying settings, place conf file to /usr/local/nginx/conf/ and start your server.

Using nginx as simple web server for static files

Nginx can be easily set up as efficient web server for static files distribution. I am using this configuration in my projects on images.someproject.com sub-domains for images distribution.

Sample configuration file can be downloaded here.

Using nginx as web server with PHP support

If you need to use nginx with PHP, you can setup PHP as FastCGI and let nginx to forward all PHP queries to some FastCGI port (tcp/socket). To use this configuration you need to start PHP as FastCGI using some third party software like spawn-fcgi from lighttpd. (Notice: I am going to describe this process in one of the future posts.)

To enable PHP support, you need to add special location section to your config file:

1
2
3
4
5
6
7
8
9
10
11
12
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
  fastcgi_pass   127.0.0.1:12345;
  fastcgi_index  index.php;

  fastcgi_param  SCRIPT_FILENAME  /usr/local/nginx/html$fastcgi_script_name;
  fastcgi_param  QUERY_STRING     $query_string;
  fastcgi_param  REQUEST_METHOD   $request_method;
  fastcgi_param  CONTENT_TYPE     $content_type;
  fastcgi_param  CONTENT_LENGTH   $content_length;
}

Sample configuration file can be downloaded here.

Using nginx as web server with SSI support

Server-Side Includes (aka SSI) is another interesting feature of nginx. As for now, following ssi instructions are supported: config, echo, if, include, set.

SSI support can be anabled by single line configuration command in your config file:

1
2
3
4
    location / {
        ssi  on;
        ...
    }

Sample configuration file can be downloaded here.

Using nginx as https-enabled web server

You need https-access to your Nginx-powered site? No problems! Nginx supports https and can be used to implement secured web-server with SSLv2, SSLv3 or TLSv1.

To enable https-support you should have certificate and key files. How to obtain them, you can read in SSL FAQ. When you will obtain them, you can enable ssl-module:

1
2
3
4
5
6
7
8
    server {
        listen               443;
        ssl                  on;
        ssl_certificate      /usr/local/nginx/conf/cert.pem;
        ssl_certificate_key  /usr/local/nginx/conf/cert.key;
        keepalive_timeout    70;
        ...
    }

Sample configuration file can be downloaded here.

Using nginx as reverse-proxy server before some another web-server

If you have some large web-site and you have noticed, that your Apache can not handle more load, you can put nginx before your primary web-server to use it as light reverse-proxy and as web-server to handle requests to static files.

Thanks to nginx flexibility, you can pass any types of requests to backend server by using location sections (all files, only dynamic content requests or some specific locations in your web-server tree):

1
2
3
4
location / {
    proxy_pass        http://localhost:8000/;
    proxy_set_header  X-Real-IP  $remote_addr;
}

Sample configuration file can be downloaded here.

Using nginx for virtual hosting platforms

One of the interesting use cases for Nginx is virtual hosting platform because it meets all requirements for good hosting server: it is efficient, it supports all popular virtual hosting methods and it has very good internal structure, so it can be easily extended in for any specific areas.

As for now, it is being used by many hosting companies as reverse proxy and I am using it on my free hosting service with millions unique visitors per day.

If you vant to try virtual hosting feature, you can create additional server sections in your config file (first section will be default):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
http {
    server {
        listen  192.168.10.1;
        listen  192.168.10.1:8000;

        server_name   one.example.com  www.one.example.com;
        ...
    }

    server {
        listen  192.168.10.1;
        listen  192.168.10.2:8000;
        listen  9000;

        server_name   two.example.com  www.two.example.com
                      three.example.com  www.three.example.com;
        ...
    }

    server {
        listen  9000;

        server_name   four.example.com  www.four.example.com;
        ...
    }
}

Sample configuration file for small virtual hosting can be downloaded here.

As you can see from my small overview, nginx is very flexible software and you can do many interesting things with it. If you have any comments, questions or suggestions, feel free to drop them here in comments for this article and I will try to answer for all of them.


Related posts:

  1. Using Nginx As Reverse-Proxy Server On High-Loaded Sites
  2. Fiddler – HTTP Debugging Proxy
  3. Unofficial Debian GNU/Linux Repositories Overview
  4. Monitoring nginx Server Statistics With rrdtool
  5. Nginx – Small, But Very Powerful and Efficient Web Server

31 Responses to this entry

nginx, Yet Another Rails Deployment Option says:

[...] I’m not going to discuss all the options, but if you’re looking for what appears to be (at the moment) a setup that is a breeze to install and will churn out more requests/second than anything else, read on.One of the downsides to this setup is that the reverse proxy server we will be using, nginx, is a Russian project with almost no English documentation. Although, there seems to be at least two capable Rails developers (1, 2) who are vouching for its speed and stability. [...]

joe says:

When using nginx in reverse proxy mode, is it possible to have nginx cache the result it got from the backend server (say for 1 minute) and just serve that without asking the backend server any more (until the 1 minute is up…)?

Scoundrel says:

joe,
Actually, no. Nginx has only non-caching reverse proxying mode. But if your backend is some dynamic application on php/perl/java/etc, you can use memcached module to cache your answers and then nginx can get pages from cache.

matthew says:

I’m running nginx with a mongrel process in the background to serve RoR applications, but I’m having trouble getting nginx to serve static HTML pages from the document root. The server passes all requests, regardless of whether there is a directory/file in the document root to mongrel.

For reference, I’ve uploaded my configuration file to a different server: http://macographie.com/nginx.conf.txt

As you’ll see, I have two virtual hosts defined. Eventually, I would like to have both hosts capable of server both RoR applications and static server content.

Thanks in advance for any advice.

Ian says:

Thanks for the resource. How do you have nginx reverse-proxy to http and https for apache?

It looks really interesting, can’t wait to try it out.

Scoundrel says:

2Ian: You can take a look at sample config file from nginx distribution. there is some https example.

All ideas are the same but you need some additional params in server section of config to assign specific certificates for virtual host.

Scoundrel says:

2matthew: Take a look at my post about using nginx with rails and mongrel. there is some config file with rails caching support.

Ian says:

I just thought of something…

If nginx is running the ssl and reverse proxying to apache, does the _Apache_ have to be running ssl…or is the connection between nginx and apache encrypted. Just thought of that after reading some info on Pound and seeing how it acts as an SSL wrapper.

Scoundrel says:

2Ian: AFAIU, you can setup non-encrypted connection between nginx and apache. As for pound, afair, it is simple tcp balancer, so it may require ssl on apache because it would simple proxy users connection on ISO Model Level 3.

Ian says:

Made a partial jump last night…

Fired up nginx running an ssl connection and reverse proxying it to Apache.

All seemed to work okay. Fired up Squirrelmail and was able to read messages just fine. I did notice a problem when I tried to send message. After I hit “send” in Squirrelmail, the page wouldn’t refresh to the message list, but stayed in the message edit page. The message DID get sent (I checked) but Squirrel wouldn’t leave the compose message page.

I checked the error logs for nginx and saw this message:

SSL_do_handshake() failed (SSL: error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 aler
t bad certificate) while reading client request line, client: xxx.xxx.xxx.xxx, server: http://www.myserver.com

Here’s the server config:

server {
listen 443;
root /usr/local/apache/htdocs;
server_name http://www.myserver.com;
ssl on;
ssl_certificate /usr/local/apache/conf/server.pem;
ssl_certificate_key /usr/local/apache/conf/server.key;

ssl_session_timeout 5m;

location / {
root shtml;
index index.shtml index.html;
location / {
proxy_pass http://127.0.0.1:8080/;
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;

proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;

proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}

Scoundrel says:

2Ian: Honestly speaking, I have not so big experience with nginx+ssl… I’ve forwarded your question to russian nginx mailing list. Will answer here or by email if someone will answer about this issue.

Ian says:

2scoundrel: I might have a bit of an “aha” moment here…fired up firefox’s live headers and rec’d this after hitting the “send”:

Location: http://www.myserver.com:8080/webmail/src/right_main.php?mailbox=INBOX&sort=0&startMessage=1

So, it looks like the Apache backend is misbehaving and not trying to redirect to

“https://www.myserver.com/webmail…”

I’ve seen several pages on how to configure Apache as a reverse proxy, but can’t seem to find much on how it should be configured to be the backend.

aim says:

вот хотел спросить — а есть возможность каждому виртуальному серверу своего пользователя указать?

сейчас у меня крутится apache-mpm-itk но в общем-то мне не нужен апач на сервере. но нужно раздавать кучу всякой статики для которой судя по всему nginx подходит как нельзя лучше…

Scoundrel says:

2aim: не – нельзя. Но можно извратиться и запустить N нгинксов по одному воркеру на каждого и на них спроксировать… через нгинкс номер N+1 :-)

Ray says:

I am testing nginx with your static configuration (first example in your post) and getting some strange behaviour:

For files larger than a few hundred kB, I often get a 206 partial or a 200, but the file does not send completely. This is very irregular. Sometimes it works, sometimes not. Any ideas?

Thanks.

An example req/resp:

GET /static/f/testimage.jpg HTTP/1.1
Host: http://www.xxxx.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Range: bytes=544487-
If-Range: Wed, 04 Apr 2007 12:20:33 GMT
Cache-Control: max-age=0

HTTP/1.x 206 Partial Content
Date: Sat, 02 Jun 2007 11:15:58 GMT
Server: nginx/0.5.22
Content-Type: image/jpeg
Content-Length: 2949459
Last-Modified: Wed, 04 Apr 2007 12:20:33 GMT
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Cache-Control: max-age=315360000
Content-Range: bytes 544487-3493945/3493946
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive

nginx, Yet Another Rails Deployment Option says:

[...] This article “has moved”:http://rubyjudo.com/2006/8/27/nginx-yet-another-rails-deployment-option over to our sister spin-off blog, “RubyJudo”:http://rubyjudo.com, which focuses on more arcane technical topics than NotRocketSurgery.One of the downsides to this setup is that the reverse proxy server we will be using, nginx, is a Russian project with almost no English documentation. Although, there seems to be at least two capable Rails developers (1, 2) who are vouching for its speed and stability. [...]

Fritzie says:

hi anyone know how to get nginx to autostart on reboot.. using ssl and be able to have the passphrase ( which it always ask for on restart ) automatically entered. ??

please send answer to chrisangileri@yahoo.com

thanks muchly

K Achary says:

Hi
I am trying to configure Nginx as proxy POP3 server on a Linux 2.6.x system. When I try to use the example config files, nginx daemon says imap and mail as unrecognized words. Would appreciate any help in this regards.

achari_98 AT yahoo.com

K Achary says:

Hi,
Thanks for the previous response.
Is it possible to enable SSL between NGINX and backend POP server. Can somebody please share any example configuration to achive this.

Basically the scenario I am talking about is, the end user POP3 client talks to the NGINX pop proxy over TCP port 110, then the NGINX server talks to backend POP3 server over SSL socket say 995.

I tried compiling the NGINX with mail_ssl support, but the TCP connection between NGINX and backend pop3 server gets established but SSL session set up does not happen.

I appreciate any help in this regard.

Thanks and regards

K Achary

Anton says:

Здравствуйте. Кто нибудь в курсе как настроить nginx, так чтобы он смог обрабатывать URL большой длины т.е. длина HTTP GET запросов могла быть более 4-5 кб. При моей текущей конфигурации запросы такой длины приводят к появлению 414 ошибки.

Hans says:

Thanks for the nice overview. A question:

Could nginx be used as a HTTP wrapper for TCP protocols that do not speak HTTP, such as RTMP? Or with added SSL to function like stunnel?