How to setup Nginx with PHP FastCGI and MySQL

Nginx is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server. Igor Sysoev started development of Nginx in 2002, with the first public release in 2004. Nginx now hosts nearly 12.18% (22.2M) of active sites across all domains. Nginx is known for its high performance, stability, rich feature set, simple configuration, and low resource consumption.
Source: Nginx Website
Download Nginx
Before we can start Nginx (Engine X) installation we will need to download it first from here. The current stable release as of this writing is Nginx 1.2.1.
tar -vxzf nginx-1.2.1.tar.gz
cd nginx-1.2.1
Install Nginx
You can check the installation options on configure time before you compile Nginx to enable all the modules you want to be compiled with Nginx such as ssl_module, perl_module among others.
In this article, we are going to compile Nginx with IPv6 support and the rest of the compile options in its default values.
./configure –with-ipv6
Configuration summary
+ using system PCRE library
+ OpenSSL library is not used
+ md5: using system crypto library
+ sha1: using system crypto library
+ using system zlib library
nginx path prefix: “/usr/local/nginx”
nginx binary file: “/usr/local/nginx/sbin/nginx”
nginx configuration prefix: “/usr/local/nginx/conf”
nginx configuration file: “/usr/local/nginx/conf/nginx.conf”
nginx pid file: “/usr/local/nginx/logs/nginx.pid”
nginx error log file: “/usr/local/nginx/logs/error.log”
nginx http access log file: “/usr/local/nginx/logs/access.log”
nginx http client request body temporary files: “client_body_temp”
nginx http proxy temporary files: “proxy_temp”
nginx http fastcgi temporary files: “fastcgi_temp”
nginx http uwsgi temporary files: “uwsgi_temp”
nginx http scgi temporary files: “scgi_temp”
After the configuration is done, you can now install compile and install Nginx based on the options set during the configure time.
make && make install
After Nginx is compiled, all the files can be found in /usr/local/nginx. Below are the Nginx directives you can use to tweak or enable/disable depending on how you want your Nginx http server to be run. The default configuration should be able to serve html pages located in the html directory as defined in the location directive. Nginx configuration file can be found in /usr/local/nginx/conf
Nginx Configuration
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main ‘$remote_addr - $remote_user [$time_local] “$request” ‘
# ‘$status $body_bytes_sent “$http_referer” ‘
# ‘”$http_user_agent” “$http_x_forwarded_for”‘;
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#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 html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.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;
#}
# deny access to .htaccess files, if Apache’s document root
# concurs with nginx’s one
#
#location ~ /\.ht {
# deny all;
#}
}
# 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;
# }
#}
}
Download and Install MySQL
Download PHP
In this article, we will be using the latest stable version of PHP source which is PHP 5.4.4. Download and decompress PHP 5.4.4 and change directory to the extracted PHP source folder.
tar -vxzf php-5.4.4.tar.gz
cd php-5.4.4
It’s time to configure what PHP modules to be compiled and enabled for this installation. The command below will show you all the available options and modules you can choose to install and compile.
In this tutorial, we will be compiling PHP-FPM support and other modules such as MySQL, Curl and LibXML2.
make && make install
Once PHP is installed, you can copy and paste the script below or download it from here and put it inside the /etc/init.d directory. The script will enable you to manage the FPM process.
### BEGIN INIT INFO
# Provides: php-fcgi
# Required-Start: $nginx
# Required-Stop: $nginx
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts php over fcgi
# Description: starts php over fcgi
### END INIT INFO
(( EUID )) && echo .You need to have root priviliges.. && exit 1
BIND=127.0.0.1:9000
USER=nobody
PHP_FCGI_CHILDREN=15
PHP_FCGI_MAX_REQUESTS=1000
PHP_CGI=/usr/local/bin/php-cgi
PHP_CGI_NAME=`basename $PHP_CGI`
PHP_CGI_ARGS=”- USER=$USER PATH=/usr/local/bin PHP_FCGI_CHILDREN=$PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS=$PHP_FCGI_MAX_REQUESTS $PHP_CGI -b $BIND”
RETVAL=0
start() {
echo -n “Starting PHP FastCGI: ”
start-stop-daemon –quiet –start –background –chuid “$USER” –exec /usr/bin/env — $PHP_CGI_ARGS
RETVAL=$?
echo “$PHP_CGI_NAME.”
}
stop() {
echo -n “Stopping PHP FastCGI: ”
killall -q -w -u $USER $PHP_CGI
RETVAL=$?
echo “$PHP_CGI_NAME.”
}
case “$1″ in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo “Usage: php-fastcgi {start|stop|restart}”
exit 1
;;
esac
exit $RETVAL
Nginx PHP Configuration
It’s time to instruct Nginx to pass the PHP scripts requests to FastCGI which by default is listening on port 9000. In your nginx.conf that can be found in /usr/local/nginx/conf look for the lines below and uncomment it. By default, PHP scripts are expected to be located under “hmtl/scripts” directory but if you want to serve it within Nginx root directory then change:
into this
Below is the complete directives for enabling PHP on Nginx
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Nginx PHP Security
By default, the above configuration will allow non-php file to be executed as PHP, and to fix this you need to add file existence check. Below is what above configuration will look like after file existence check is put in place.
location ~ \.php$ {
root html;
try_files $uri =400
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
include fastcgi_params;
}
Start Nginx and PHP-FPM Services
/usr/local/nginx/sbin/nginx
You should have Nginx and PHP-FPM running by now, verify this by opening the address of your nginx server on your browser.
Test Nginx with PHP
To test if PHP is working fine, you can copy the lines below and save it as index.php. Now, try to access your nginx running server.
Nginx with PHP and MySQL Test
It’s time to test if your PHP script is able to connect to your MySQL server.
/etc/init.d/mysql start
#login as root
mysql -u root -p
#create your test database
mysql> create database test;
#add test user with test as password and grant access to the test database
mysql> grant all on test.* to test@localhost identified by ‘test’;
mysql> flush privileges;
mysql>\q
Below is a PHP script you can use to test PHP-MySQL database connectivity.
@mysql_connect(”localhost”,”test”,”test”) || die(mysql_error());
if (mysql_select_db(”test”))
{
print “Database selected successfully!”;
} else {
die(mysql_error());
}
?>
If you have questions/suggestions on doing this the better way then please do not hesitate to drop your comments.
Spread the word
del.icio.us Digg Furl Google StumbleUpon Technorati Windows Live Yahoo! Help











Leave a Comment