This is the second part of my Nginx tutorial. The first part covered the installation process. In this post, I will show you how to modify the default configuration and get your server ready to serve CMS based websites like WordPress, Drupal, Joomla, Gallery etc

Before delving into the configuration of nginx, it is important to ensure that all the prerequisite software is installed and properly configured. Like all of my tutorials, I am using Linux and specifically Fedora 20.

PHP

Install the following php and related modules:

yum install php php-fpm php-pecl-apcu php-pdo php-mcrypt php-common php-mysqlnd php-process php-gd php-pear php-pear-DB php-pgsql php-xml php-cli php-xmlrpc php-mbstring php-pecl-igbinary php-pecl-memcache php-pecl-memcached php-pecl-mongo php-pecl-jsonc

Edit the php configuration file:

vim /etc/php.ini

I recommend setting the following parameters in php.ini:

short_open_tag = On
date.timezone = Africa/Kampala (or your time zone)

Edit the php-fpm configuration file:

vim /etc/php-fpm.d/www.conf

Change the following options in www.conf:

[www]
listen = 127.0.0.1:9000
;listen.allowed_clients = 127.0.0.1
user = nginx
group = nginx

Change permissions of the php sessions directory:

chown nginx:nginx /var/lib/php

Now enable and start php-fpm service:

systemctl enable php-fpm.service && systemctl start php-fpm.service

OPENSSL

Install openssl if you plan on securing your server; which you should!

yum install openssl openssl-libs openssl-devel

Add ssl directory where certificate and key will be stored:

mkdir /etc/nginx/ssl

Generate self-signed SSL certificate and key for your webserver:

openssl req -new -x509 -out /etc/nginx/ssl/cert.pem -key /etc/nginx/ssl/cert.key -days 365

SPAWN-FCGI

Install spawn-fcgi, a simple program for spawning FastCGI processes:

yum install spawn-fcgi

Edit the environment file for spawn-fcgi:

vim /etc/sysconfig/spawn-fcgi

Make the following changes:

FCGI_SOCKET=/var/run/fcgiwrap.socket
FCGI_PROGRAM=/usr/sbin/fcgiwrap
FCGI_USER=nginx
FCGI_GROUP=nginx
FCGI_EXTRA_OPTIONS="-M 0700"
OPTIONS="-u $FCGI_USER -g $FCGI_GROUP -s $FCGI_SOCKET -S $FCGI_EXTRA_OPTIONS -F 1 -P /var/run/spawn-fcgi.pid -- $FCGI_PROGRAM"

Enable and start spawn-fcgi.service:

systemctl enable spawn-fcgi.service && systemctl start spawn-fcgi.service

FCGIWRAP

Install fcgiwrap, a simple FastCGI wrapper for CGI scripts:

cd /usr/src

Download fcgiwrap sources:

git clone https://github.com/gnosek/fcgiwrap.git
cd /usr/src/fcgiwrap
autoreconf -i
./configure --prefix=/usr
make && make install

CONFIGURATION

Nginx’s configuration files are located under /etc/nginx. And as specified by the installation configure command in the previous post, the main configuration file is: /etc/nginx/nginx.conf. This is where I will make most of my changes.

vim nginx.conf

Add the following to nginx.conf and save it:

user nginx;
worker_processes 1;
#
events {
worker_connections 1024;
}
#
http {
include mime.types;
include conf.d/*.conf;
include sites-enabled/*;
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"';
sendfile on;
keepalive_timeout 65;
#
server {
listen 80;
server_name localhost;
root html;
index index.html index.htm index.php;
autoindex on;
access_log /var/log/nginx/localhost.access.log main;
#
location / {
}
#
error_page 500 502 503 504 /50x.html;
#
location = /50x.html {
}
#
location ~ \.php$ {
include includes/php_params;
}
#
location ~* \.(cgi|chi)$ {
include includes/cgi_params;
}
# Add xmlrpc scgi support
#
location ~ ^/RPC2$ {
scgi_pass localhost:5000;
include scgi_params;
}
}
#
# HTTPS server
#
server {
listen 443 ssl;
server_name localhost;
root html;
index index.html index.htm index.php;
#
ssl_certificate ssl/cert.pem;
ssl_certificate_key ssl/cert.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
#
location / {
}
#
location ~ \.php$ {
include includes/php_params;
}
#
location ~* \.(cgi|chi)$ {
include includes/cgi_params;
}
}
}

To get details on what these directives exactly mean and the syntax used above, visit the Nginx documentation

NOTES:

Nginx is pretty picky when it comes to Syntax, so:

– The location directive is placed within a server directive.
– Also, all directives must end with a semicolon.

Like other similar programs in UNIX, you can split the configuration file into several files using the parameter: include as shown in the above file. This makes maintenance and packaging of these files easier.

Create other configuration directories:

mkdir /etc/nginx/{conf.d,includes,sites-enabled}

Add the following files to the includes directory:

vim /etc/nginx/includes/php_params

gzip off;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
fastcgi_index index.cgi;
#
fastcgi_param SCRIPT_FILENAME $document_root$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;
#
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 HTTPS $https if_not_empty;
#
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;

vim /etc/nginx/includes/cgi_params

fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
#
fastcgi_param SCRIPT_FILENAME $document_root$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;
#
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 HTTPS $https if_not_empty;
#
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;

VIRTUAL HOSTS

Now let’s configure a virtual host. In this tutorial, I use example.com as the domain name.

vim /etc/nginx/sites-enabled/example.com

server {
listen 80;
#
server_name zikusooka.com www.zikusooka.com;
root html/vhost.example;
index index.html index.htm index.php;
#
location / {
}
#
location ~ \.php$ {
include includes/php_params;
}
#
location ~* \.(cgi|chi)$ {
include includes/cgi_params;
}
}

WEB CONTENT

Add an index file to the main server’s root directory, for example:

vim /usr/share/nginx/html/index.html

Add the following and save (This is just for testing, any HTML web page should work):

<HTML>
<B>Hello World. Welcome to my Nginx web server!</B>
<HTML>

Create the document root directory for your virtual host:

mkdir /usr/share/nginx/html/example.com

Add your document root in the above created directory. For Example create a file named index.php.

vim /usr/share/nginx/html/example.com/index.php

Add the following and save (This is just to test php, so any simple php page should work):

<?
phpinfo();
?>

TESTING

Finally, restart nginx web server:

systemctl start nginx

If all goes well, you should now be able to browse html, php, and cgi pages on your server. You can then proceed to installing your WordPress or other content management system.