Topics

Install Nginx 1.0.12 for PHP-FPM on CentOS 6.2

– Make sure to check PHP-FPM, memcached and MYSQL posts.
– get the latest package from wiki.nginx.org

mkdir 
cd 
wget http://.org/download/-1.0.12.tar.gz
tar xfz -1.0.12.tar.gz 
cd -1.0.12

#Change server string
vi src/http/_http_header_filter_module.c
#change
static char _http_server_string[] = "Server: example." CRLF;
static char _http_server_full_string[] = "Server: example.com" CRLF;

#change
vi src/http/_http_special_response.c
# replace '"<hr><center></center>" CRLF' and '"<hr><center>" _VER "</center>" CRLF'
"<hr><center>example.com</center>" CRLF

#create tmp dirs
mkdir /server/tmp /server/tmp/ /server/tmp//client /server/tmp//fcgi /server/tmp//proxy
chmod -R 777 /server/tmp

-install Nginx

./configure \
  --prefix=/server \
  --sbin-path=/usr/sbin/nginx \
  ---path=/server/nginx. \
  --error-log-path=/var/log/nginx/error.log \
  --http-log-path=/var/log/nginx/access.log \
  --pid-path=/var/run/nginx/nginx.pid  \
  --lock-path=/var/lock/nginx.lock \
  --user=www \
  --group=www \
  --with-http_stub_status_module \
	--without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module \
  --http-client-body-temp-path=/server/tmp/nginx/client/ \
  --http-proxy-temp-path=/server/tmp/nginx/proxy/ \
  --http--temp-path=/server/tmp/nginx/fcgi/ 
make; make install;
mkdir /var/log/nginx
chown www:www /var/log/nginx

– add init.d script

vi /etc/init.d/nginx
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15 
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 
# processname: nginx
# config:      /server/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid
 
# Source function library.
. /etc/rc.d/init.d/functions
 
# Source .
. /etc/sysconfig/network
 
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
 
nginx="/usr/sbin/nginx"
prog=$(basename $nginx)
 
NGINX_CONF_FILE="/server/nginx.conf"
 
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
 
lockfile=/var/lock/subsys/nginx
 
make_dirs() {
   # make required directories
   user=`$nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
   if [ -z "`grep $user /etc/passwd`" ]; then
       useradd -M -s /bin/nologin $user
   fi
   options=`$nginx -V 2>&1 | grep 'configure arguments:'`
    opt in $options; do
       if [ `echo $opt | grep '.*-temp-path'` ]; then
           value=`echo $opt | cut -d "=" -f 2`
           if [ ! -d "$value" ]; then
               # echo "creating" $value
               mkdir -p $value && chown -R $user $value
           fi
       fi
   done
}
 
start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}
 
stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}
 
restart() {
    configtest || return $?
    stop
    sleep 1
    start
}
 
reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}
 
force_reload() {
    restart
}
 
configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}
 
rh_status() {
    status $prog
}
 
rh_status_q() {
    rh_status >/dev/null 2>&1
}
 
case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac

– test nginx

cp conf/nginx.conf /server/
chmod +x /etc/init.d/nginx
/etc/init.d/nginx start
lynx -dump localhost

You should see “Welcome to nginx!”

– configure nginx for php-fpm more info

vi /server/nginx.conf

user  www www;
# get the number of processor cores ex: 4 - 12 - 24
# cat /proc/cpuinfo |grep processor  
worker_processes  1;



events {
	#increase this depending on your server config - ex: 1024 - 51200 - 500000
	worker_connections  1024;
	# use [ kqueue | rtsig | epoll | /dev/poll | select | poll ] ;
	use epoll;
}


http {
	include	   mime.types;
	default_type  application/octet-stream;

	#http://wiki.nginx.org/NginxHttpGzipModule
	gzip on;
	gzip_http_version 1.0;
	#1-9
	gzip_comp_level 7;
	gzip_proxied any;
	gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
	gzip_min_length  2000;
	gzip_buffers 16 8k;
	gzip_disable "MSIE [1-6]\.(?!.*SV1)";
	
	#hide ngnix version
	server_tokens off;

	#sendfile
	sendfile		on;
	tcp_nopush	 on;
	
	## Timeouts
	client_body_timeout   5;
	client_header_timeout 5;
	send_timeout		  5;
	#keepalive_timeout  75 20;
	keepalive_timeout  10 10;
	tcp_nodelay	 on;

	#http://wiki.nginx.org/NginxHttpLimitZoneModule
	#limits
	limit_zone gulag $binary_remote_addr 2m;
	limit_conn  gulag 10;
	ignore_invalid_headers  on;

	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
					  '$status $body_bytes_sent "$http_referer" '
					  '"$http_user_agent" "$http_x_forwarded_for"';

	#custom log files
	#access_log off;
	#error_log /server/log/nginx/error.log;


	#error_ 404  /errors/error.php?error=404;
	#error_ 402 405 406 407 408 409 410 411 412 413 415 416 417 //status-000.html;
	#error_ 400 /errs/status-400.html ;
	#error_ 401 /errs/status-401.html ;
	#error_ 403 /errs/status-403.html ;
	#error_ 414 /errs/status-414.html ;
	#error_ 500 501 502 504 /errs/status-500.html;

	server {
		listen	   80;
		server_name  *.example.com example.com;

		expires	 1d;

		charset utf-8;
		
		#error_log /server/log/nginx/example.com.error.log;
		#access_log  /server/log/nginx/example.com.access.log  main;

		root   /server/sites/example.com;
		index  index.php;

		##Only allow GET and HEAD request methods
		if ($request_method !~ ^(GET|HEAD)$ ) {
			return 444;
		}

		## Deny illegal Host headers
		#if ($host !~* ^([^\.]*\.?)example\.com$ ) {
		#	return 444;
		#}

		#redirect all subdomains to www.example.com
		if ($host != 'www.example.com' ) {
			rewrite  ^/(.*)$  http://www.example.com/$1  permanent;
		}

		## Deny certain User-Agents (case insensitive)
		## The ~* makes it case insensitive as opposed to just a ~
		#if ($http_user_agent ~* (Baiduspider|Jullo|libwww-perl|PuxaRapido) ) {
		#	return 444;
		#}

		 / {
			##normal config
			index index.php;

			##rewrite rule ex
			#rewrite ^/([0-9]+\.)(png|gif|jpg)(\?.*)?$	/imgs/$1$2	last;
			#rewrite ^/sitemap_(.+).gz$ /sitemap.php?name=$1 last;

			##create 301 permanent redirection
			#rewrite ^/old_link$ /new_link permanent;

			##redirect all requests to index.php
			#try_files $uri $uri/ /index.php;
						
			##allow deny
			#allow 123.456.7.89;
			#deny all;
			
			##limit requests
			#limit_rate_after 1m;
			#limit_rate 100k;
		}		
		
		##wordpress
		 /blog {
		   try_files $uri $uri/ /blog/index.php?q=$uri&$args;
		}		
		
		
		#http://wiki.nginx.org/NginxHttpFcgiModule
		#php-fpm
		 ~ \.php {
			#fixing example.com/test.gif/blah.php
			#Since php 5.3.9 php-fpm added 'security.limit_extensions' which limits
			#the extensions of the main script FPM will allow to parse.
			#remove this if you have 'security.limit_extensions' enabled
			#try_files $uri =404;
			fastcgi_split_path_info ^(.+\.php)(/.+)$;

			include		/server/fastcgi_params;
		}
		
		# proxy the PHP scripts to Apache listening on 127.0.0.1:80
		# ~ \.php$ {
		#	proxy_pass   http://127.0.0.1;
		#}

		# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
		#
		# ~ \.php$ {
		#	root		   html;
		#	fastcgi_pass   127.0.0.1:9000;
		#	fastcgi_index  index.php;
		#	fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
		#	include		fastcgi_params;
		#}


		
		## Restricted Access directory
		 ~ /\. {
			autoindex on;
			index index.php;
			#local ip
			allow 127.0.0.1;
			deny all;
		}

		#http://wiki.nginx.org/HttpCoreModule
		#sendfile example
		#PHP usage : header("X-Accel-Redirect: /download/filename.gz" );
		 /download/ {
				add_header Content-Encoding gzip;
				gzip off;
				internal;
				alias /server/sites/example.com/download/;
		}
		
		#http://wiki.nginx.org/NginxHttpStubStatusModule
		#access using lynx -dump http://www.example.com/nginx_status
		# /nginx_status {
		#	stub_status on;
		#	#local ip
		#	allow 127.0.0.1;
		#	deny all;
		#}
		
		#http://wiki.nginx.org/HttpAuthBasicModule
		#auth_basic
		 /admincp/ {
			auth_basic "RESTRICTED ACCESS";
			#http://wiki.nginx.org/Faq#How_do_I_generate_an_.htpasswd_file_without_having_Apache_tools_installed.3F
			auth_basic_user_file /server/secure/.htpasswd;
		}

		#cutom log
		 ~* ^/special/.*?\.png$ {
			access_log /server/log/nginx/example.com.special.access.log main;
		}
		
		#custom error file
		 ~* ^/skip_error/.*?\.jpg$ {
			error_log off;
			error_ 404 = /404.gif;
		}
		
		#add cache headers for static files
		location ~ /.*\.(gif|js|png|jpg|css)$ {
			expires	 1y;
			add_header Cache-Control public;
			
		}
		
		## Stop Image and Document Hijacking
		location ~* \.(jpg|gif|ico|png|css|js)$ {
			if ( $http_referer !~ ^http://([^/]+\.)?example\.com/ ) {
			  return 403;
			}
		}


	}


	# another virtual host using mix of IP-, name-, and port-based configuration
	#
	#server {
	#	listen	   8000;
	#	listen	   somename:8080;
	#	server_name  somename  alias  another.alias;

	#	location / {
	#		root   html;
	#		index  index.html index.htm;
	#	}
	#}


	# HTTPS server
	#
	#server {
	#	listen	   443;
	#	server_name  localhost;

	#	ssl				  on;
	#	ssl_certificate	  cert.pem;
	#	ssl_certificate_key  cert.key;

	#	ssl_session_timeout  5m;

	#	ssl_protocols  SSLv2 SSLv3 TLSv1;
	#	ssl_ciphers  HIGH:!aNULL:!MD5;
	#	ssl_prefer_server_ciphers   on;

	#	location / {
	#		root   html;
	#		index  index.html index.htm;
	#	}
	#}

}

– edit fastcgi_params for php-fpm

vi /server/fastcgi_params
fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index  index.php;
fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

fastcgi_connect_timeout 10;
fastcgi_send_timeout 180;#3 min
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 8 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
 
fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
#fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
#fastcgi_param  REDIRECT_STATUS    200;

– setup logrotate for Nginx

vi /etc/logrotate.d/nginx

– add /etc/logrotate.d/nginx

/var/log/nginx/*.log
{
missingok
copytruncate
rotate 2
#mail root
size=50M
compress
notifempty
sharedscripts
postrotate
/etc/init.d/nginx reload
endscript
}

– start Nginx and PHP-FPM

/etc/init.d/php-fpm restart
/etc/init.d/nginx restart

– testing performance

Server info :
~: cat /proc/cpuinfo
processor	: 0
model name	: Intel(R) Core(TM) i7 CPU       Q 720  @ 1.60GHz
cpu MHz		: 1596.009
cache size	: 6144 KB

~: free -m
             total       used       free     shared    buffers     cached
Mem:           996        312        683          0         66         66

add helloworld.php to /server/sites/example.com/

<?php
for( $i=0; $i < 1000; $i++)
	echo 'Hello World';
?>

– testing performance with ab

#benchmark using ab with compression enabled
ab -n2000 -c400  -H 'Accept-Encoding: gzip,deflate'  http://www.example.com/helloworld.php

#results
Requests per second:    1471.13 [#/sec] (mean)
Time per request:       271.899 [ms] (mean)
Time per request:       0.680 [ms] (mean, across all concurrent requests)