How to configure nginx for use with WordPress and other CMS based websites
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.
How to install Nginx web server on a Raspberry Pi using sources
For a long time Apache has been the software choice for admins and developers wishing to setup a web server. It is therefore no surprise, that Apache dominates when it comes to the most deployed web server on the Internet today. Take a look at Netcraft’s survey as of January 2015.
I have used Apache since the early days of the Internet, but lately, I’ve noticed its become very bloated. In fact for any embedded developers out there, Apache is these days frown upon, when it comes to arm based devices such as the Raspberry Pi. Here is where Nginx comes in. It is very light weight and fast, and can easily be installed in your embedded and other web server projects. Try it, and you may find yourself liking it so much, that you’ll switch from running Apache in your enterprise or hosting environment.
Nginx is an open source high performance HTTP and reverse proxy server. It is very scalable and very suitable for production environments that need to serve many requests. Compared to Apache, Nginx handles requests using an asynchronous event-driven approach. Apache uses a process/thread oriented approach which makes it unpredictable when it comes to very high loads.
While installation via packages managers such as yum or apt is possible, I chose to install Nginx on a Raspberry Pi using sources. Going the source-install route has some benefits, one of which is that you get the latest version of Nginx, which usually takes sometime to make its way to distribution package repositories. Lets get started with the install.
Download sources:
cd /tmp
wget -c http://nginx.org/download/nginx-1.7.10.tar.gz
tar zxvf /tmp/nginx-1.7.10.tar.gz -C /usr/src
cd /usr/src/nginx-1.7.10
./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --with-perl_modules_path=/usr/lib/perl5/auto/nginx --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/lock/subsys/nginx --user=nginx --group=nginx --with-http_addition_module --with-http_auth_request_module --with-http_degradation_module --with-http_perl_module --with-http_flv_module --with-http_geoip_module --with-google_perftools_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_image_filter_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_dav_module --with-http_xslt_module --with-file-aio --with-ipv6 --with-mail --with-mail_ssl_module --with-ld-opt="-Wl,-E"
Notice that I added several optional modules, which means any dependencies need to be resolved before you proceed. You can read about built-in and optional modules at: http://wiki.nginx.org/Modules. On Fedora 20 I ran into errors starting nginx, so I added the configure option –with-ld-opt=”-Wl,-E” to resolve it
make && make install
Create the server user and group:
On Red Hat based systems like Fedora, run the following command to add a user and group for the webserver:
useradd -M -r -c "Nginx Web Server" -s /sbin/nologin -d /var/spool/nginx nginx
Setup directory permissions:
Give nginx user the permission to use directories
chown -R nginx:nginx /usr/share/nginx
chown -R nginx:nginx /var/log/nginx
Add the start up script
In order to automatically start nginx at boot time, you will need to setup an init script. Luckily, the folks over at Nginx have put together several star/stop scripts depending on your Linux distribution. You can collect them at: http://wiki.nginx.org/InitScripts
Since Am using Fedora and hence systemd, the following is the start up script:
[Unit]
Description=The nginx HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Save this file at: /usr/lib/systemd/system/nginx.service.
Enable it to start automatically at boot.
systemctl enable nginx.service.
Testing:
Start Nginx:
systemctl start nginx.service
check to see if Nginx is listening on port 80
lsof -i :80
(You need the package lsof, if not use netstat)
Open your browser and go to:
http://localhost/
You will be greeted by a welcome HTML page.
That’s it for now. Next time, I will take a look at how to configure Nginx, and even enable PHP, so you can install most Content Management Systems (CMS) like wordpress on your web server easily.
How to Migrate to Digital TV in Uganda – A consumer’s Experience
Are you still puzzled by Digital TV Migration? Are you wondering how to start watching Free-to-Air DTV broadcasts in your area? Help is here inform of a consumer’s experience. Julian Mwine has put together a seven minute video, explaining the process involved in migrating to Digital TV in Uganda. Keep in mind, despite the deadline being 4 months away, we are still in early stages.
Connect to 3G networks in Uganda using the Linux command line
If you are a Linux user living in Uganda and use 3G internet, you may want to try out my tools to connect to the Internet. These are a couple of scripts I created a while back, however, I’ve now updated them to allow for the following:
- You can now connect to Airtel, Orange/Africell, MTN, UTL, and Smart telecom.
- I have added the capability to use your PC (or device such as a raspberry Pi) as a router, this way several devices can access the Internet using one 3g dongle. You can create a MiFI of sorts if you’re inclined to.
- Query your modems for: EMEI, Serial, IMSI numbers, Lock status, Model/firmware version, etc.
- A few BUG fixes and script clean ups.
Want to try it out? Visit my Github repository
How to stream FM Radio using the Command Line in Linux
With all the advancements in IT, one piece of technology has persisted and seems not ready to die yet: FM radio. Unlike its companion AM, FM radio continues to be the primary source of information and entertainment. For example, in the United States, FM radio is still alive, and is used by many as a discovery medium. Most people especially teenagers will tell you that they first heard a song on terrestrial FM radio, before they went on to streaming sites such as YouTube, Spotify etc. In Uganda, like elsewhere in Africa, expect traditional FM radio to continue being king of information. Our limited Internet infrastructure is still very limited to a small section of the population, speeds are still horrible, so on-line radio is still not an option for many.
As I work on my upcoming digital product, I debated a lot about whether to include FM radio as a feature on this device. With all the above said, there was no doubt, FM radio would quickly become one of the most requested for features. So I got down to playing, recording, and streaming Live FM radio using the Linux command line. The cool bit is that you can stream a live FM radio show to all your devices in the house or office. No need for you to buy a radio.
What you need:
a) Analog Video for Linux (V4L2) FM radio tuner. You can either use a USB stick or PCI-E based card.
b) Linux distribution – Am using Fedora 20. But any Linux distro will work, although you will need to adjust the install commands where necessary.
Available Linux CLI tools:
There are a whole lot of GUI based applications that you can use to play radio in Linux, For example Gnomeradio, Kradio, gradio etc. However, using the command line gives you much more flexibility, as the following commands illustrate. You can control an FM radio tuner using CLI tools like MPlayer (which is installed on most Linux distros), ivtv-radio, and fmtools. In this ‘how to,’ I use the latter, fmtools, which comes with a set of tools (fm and fmscan) for controlling V4l2 based tuners.
Installation:
1. Install fmtools
yum install fmtools
(On Red-Hat based Distros such as Fedora, CentOS)
2. Install SoX
yum install sox
(On Red-Hat based Distros such as Fedora, CentOS)
3. Install VLC
yum install vlc
(On Red-Hat based Distros such as Fedora, CentOS)
FM Radio Commands
The basic arguments for the fm command line tool are:
fm -d [device] -T [time] [freq] [on|off] [percentage]
-d The radio device created by your USB or PCI based tuner
-T The duration of play
-q quiet | No verbose
[Freq] The radio channel
[on|off] Turn on or mute radio
[Volume] The desired volume
Tune and play FM 91.3
fm -q -d /dev/radio0 -T forever 91.3 100%
Mute:
fm -q -d /dev/radio0 off
Unmute:
fm -q -d /dev/radio0 on
Recording FM Radio
To record FM radio, use parec a utility that is packaged with pulseaudio, the default sound subsystem on most Linux distros.
1. First tune to the desired radio station as shown above.
2. Capture the audio:
parec -d alsa_output.pci-0000_01_01.0.analog-stereo.monitor | sox -t raw -r 43000 -e signed -L -b 16 -c 2 - /var/tmp/fmradio.wav
NOTE: You will need to change the variable -d i.e. output pulse device for your system. To find yours, just run the command:
pactl list | grep -A2 '^Source #' | grep 'Name: .*\.monitor$' | awk '{print $NF}' | tail -1
The recording will be stored at /var/tmp/fmradio.wav. You can change that to another location if you wish.
Stream FM Radio to other PCs or devices (such as smart phones)
Start the capture process as shown above, and proceed immediately to the stream command below:
vlc -I dummy -I http --daemon --no-video --no-sout-display-video --verbose 2 /var/tmp/fmradio.wav --sout #duplicate{dst=standard{access=http,mux=asf{title='JambulaRadio',author=FM-91.3-Radio-Kampala(Uganda),copyright=2015-2016-Joseph-Zikusooka-All-rights-reserved,comment=Broadcasting-Live-from-Kampala-Uganda,rating=PG14},dst=192.168.0.10:8090},dst=standard{access=http,mux=asf{title='FM-Radio',author=FM-91.3-Radio-Kampala(Uganda),copyright=2015-2016-Joseph-Zikusooka-All-rights-reserved,comment=Broadcasting-Live-from-Kampala-Uganda,rating=PG14},dst=172.16.0.1:8080}"}
NOTE: Here, I’m streaming on both wired and wireless LAN, and my machine IP addresses are 192.168.0.10, and 172.16.0.1 respectively. The http stream port is 8080. Change these to suit your environment.
If you are using a wired connection, use VLC on your client PC or mobile phone to access the stream as follows:
vlc http://192.168.0.10:8080
If on Wireless, use vlc on your client PC or mobile phone to access the stream as follows:
vlc http://172.16.0.1:8080
Enjoy!