Quick Guide to Nginx

Introduction

Like Lighttpd, Nginx is a faster and leaner alternative to Apache. It can be used as either a regular web server or a reverse proxy. This is a short HOWTO on installing Nginx with PHP5 in FastCGI mode on Ubuntu (10.04).

To read

Nginx.1.Web.Server.Implementation.Cookbook_Dipankar.Sarkar.2011.pdf

Nginx.HTTP.Server_Clement.Nedelcu.2nd.edition.2013.pdf

Mastering.Nginx_Dimitri.Aivaliotis.2013.pdf

 

http://wiki.nginx.org/Pitfalls

http://wiki.nginx.org/QuickStart

http://wiki.nginx.org/Configuration

NONE /usr/share/doc/nginx-doc/examples/

 

Third party modules

NginxFullExample

Wordpress

DONE http://till.klampaeckel.de/blog/archives/30-PHP-performance-III-Running-nginx.html

http://www.sitepoint.com/blogs/2010/05/04/php-with-nginx-is-about-to-become-a-lot-easier/

http://blog.hbis.fr/2009/03/18/nginx-fastcgi-php/

Setup

From package (Ubuntu)

Install Nginx and check that it works OK before moving on to adding PHP5 to the mix:

  1. apt-get install nginx
  2. /etc/init.d/nginx start
  3. netstat -lpn
  4. http://nginx-srv/
  5. /etc/init.d/nginx stop
  6. update-rc.d nginx defaults
  7. chown -R www-data.www-data /var/www

To remove Nginx: apt-get --purge remove nginx ; rm -Rf /var/www

Note that if you perform multiple install/remove cycles, you might need to clean the database:

dpkg --purge $(COLUMNS=200 dpkg -l | grep "^rc" | tr -s ' ' | cut -d ' ' -f 2)

From source

  1. cd /usr/src
  2. wget -c http://sysoev.ru/nginx/nginx-0.7.67.tar.gz
  3. tar xzvf ./nginx-0.7.67.tar.gz
  4. cd nginx-0.7.67
  5. ./configure
  6. make
  7. make install

If you want to find where the binaries will be installed before running "make install", use "make -n install".

More information:

Configuration infos

The main configuration file is /etc/nginx.conf, which can include yet more configuration files through the "include" command; In particular, additional files can be found in /etc/nginx/conf.d/ and /etc/nginx/sites-available/ (/etc/nginx/sites-enabled/default is a symlink to /etc/nginx/sites-available/default.)

By default, the main file contains two contexts: events and http. The http context contains two includes pointing to ./conf.d/* and ./sites-available/*.

The first thing you probably want to do is save a copy and start experimenting with ./sites-available/default.

Basic nginx.conf

#user  nobody;
worker_processes  2;
 
error_log  /tmp/ngx_openresty-1.4.3.6/install/usr/local/openresty/nginx/logs/error.log;
 
events {
    worker_connections  1024;
}
 
http {
    include       mime.types;
    default_type  application/octet-stream;
 
    sendfile        on;
 
    keepalive_timeout  65;
 
    server {
        listen       12345;
        server_name  localhost;
 
        root /tmp/ngx_openresty-1.4.3.6/install/usr/local/openresty/nginx/html;
 
        location / {
            #root   html;
            index  index.html index.htm;
        }
 
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            #root   html;
        }
    }
}

Checking how Nginx was compiled

nginx -V

Before using a directive in nginx.conf, make sure the relevant module was compiled in the application.

Handling 404 and 50x

Here's an example from Nginx 1 Web Server Implementation Cookbook:

location @fallback (
    proxy_pass http://backend;
)
 
error_page 404 /404.html;
error_page 502 503 504 /50x.html;
error_page 403 http://example1.com/forbidden.html;
error_page 404 = @fallback;
error_page 404 =200 /.empty.gif;

Testing a new configuration file

nginx -t (checks the default configuration file)

nginx -t -c /home/joe/test.conf

Securing a directory

Although putting sensitive information on a public server is never a good idea, you might need to. Here's how to protect a directory by requiring the user to type a login and password:

  1. Generate a password: http://www.askapache.com/online-tools/htpasswd-generator/. The Digest algorithm doesn't seem supported by Nginx, so I chose the MD5 format
  2. Create a file to hold this information. For added protection, it should reside outside the web docroot, eg. /etc/nginx/.passwd, and paste the login/password line in .passwd
  3. As child processes spawned by Nginx run as www-data, secure this file thusly: chown www-data:www-data /etc/nginx/.passwd ; chmod 640 /etc/nginx/.passwd
  4. Edit /etc/nginx/sites-enabled/default to add this section in the server block:

    location /mysecret/ {
        auth_basic "Restricted";
        auth_basic_user_file /etc/nginx/.passwd;
    }
     
  5. Create the actual directory in the docroot: mkdir /usr/share/nginx/www/mysecret ; chown -R www-data:www-data /usr/share/nginx/www/
  6. As, by default, directory listing is not allowed, create an index.html file in the directory
  7. Finally, tell Nginx to re-read its configuration file (service nginx reload), connect from a remote browser, and check that you are indeed prompted for a login/password. Logs are available in /var/log/nginx/.

Hosting multiple sites (Server blocks)

If you need to host multiple web sites on a single server, you need to configure Nginx to support so-called virtual hosts through one or more Server blocks. All you need to do is add server blocks to the sites-enables/default, and it will know which site to deliver based on the hostname used by the browser:

http://wiki.nginx.org/Pitfalls

http://wiki.nginx.org/QuickStart

http://wiki.nginx.org/Configuration

 

# Default catch-all virtual host when reached through IP
server {
        root /usr/share/nginx/www;
        index index.html index.htm;
        server_name _;
        access_log /var/log/nginx/default.access.log;
        error_log /var/log/nginx/default.error.log;
}

server {
    root /usr/share/nginx/www/site1;
    index index.html index.htm;
    #This is how Nginx knows how to map the hostname to an actual site
    server_name www.site1.com;
}

server {
    root /usr/share/nginx/www/site2;
    index index.html index.htm;
    #so the server can be reached with or without "www"
    server_name www.site2.com site2.com;
}

Scripting with Python through WSGI

Scripting with PHP5

There are several ways to run PHP5 with Nginx:

We'll use PHP-FPM to run PHP5.

Through packages

  1. apt-get install php5-cli php5-common php5-suhosin php5-mysql
  2. apt-get install python-software-properties
  3. add-apt-repository ppa:brianmercer/php
  4. apt-get update
  5. apt-get install php5-fpm php5-cgi
  6. /etc/init.d/php5-fpm start
  7. "netstat -nat" and "ps aux", and check that a group of php5-fpm processes are running as www-data

Tips:

By default, the followings files in /etc/nginx/ don't need to be modified: nginx.conf, fastcgi_params. The only file you need to edit for a standard install is /etc/nginx/sites-available/default. Here's an example:

server {
    listen 80 default;
    server_name  localhost;
    access_log  /var/log/nginx/localhost.access.log;
    root   /var/www/nginx-default;
 
    location / {
        index index.php index.html;
    }
 
    location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
      access_log        off;
      expires           30d;
    }
 
    location ~ \.php$ {
        include fastcgi_params;
 
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_pass   backend;
        fastcgi_index  index.php;
 
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
 
        fastcgi_intercept_errors        on;
        fastcgi_ignore_client_abort     off;
        fastcgi_connect_timeout 60;
        fastcgi_send_timeout 180;
        fastcgi_read_timeout 180;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;
    }
 
## Disable viewing .htaccess & .htpassword
    location ~ /\.ht {
        deny  all;
    }
}
 
upstream backend {
        server 127.0.0.1:9000;
}

Next, add the usual PHP script to check that it works:

  1. cd /var/www/nginx-default/; mv index.html index.html.orig
  2. vi index.php: <?php phpinfo(); ?>

Restart Nginx: /etc/init.d/nginx restart

Aim your browser to the server and check that it works as expected.

Check for errors in /var/log/nginx/error.log.

php.ini

If you make any change to php.ini, remember to /etc/init.d/php5-fpm restart

Does FPM use both INI files below?

# ll /etc/php5/fpm/

conf.d -> ../conf.d/

php5-fpm.conf

php.ini

Should I include this file to use PDO in PHP5 scripts?

# ll /etc/php5/conf.d/

pdo.ini

suhosin.ini

Q&A

How to secure server by blacklisting host trying to access same ressource (eg. PhpMyAdmin) too many times?

HTTPS for just one sub-directory?

Why does lack of trailing slash redirects to localhost?

http://192.168.0.3/punbb -> http://localhost/punbb/

http://192.168.0.3/punbb/ OK

How to change the port on which Nginx is listening?

Updated /etc/nginx/sites-available/default, restarted both PHP5-FPM and Nginx: redirected to 80 with 301 error

Resources