Index.
07-Jan-2012: initial release. 14-Jan-2012: added gzip compression.
Introduction.
This article describes how to install virtual web servers using Nginx, PHP and MySQL. PHP and Nginx will be installed on this DMZ server, but MySQL should already be running on the Home Server host. When MySQL runs on the host, you can safely use phpmyadmin on the host because it won’t be available from the Internet, only from within your network. Using only one MySQL installation saves system resources. With a firewall rule we only allow MySQL from this DMZ host, and in MySQL itself only databases that are needed by the DMZ machine will be allowed to do so.
Virtual web hosting for IPv4 is name based only, in general you will have to share just one public IPv4 address. For IPv6 we have so many available IPv6 addresses that we will give each virtual server it’s own IPv6 address. Virtual web hosting with just one IPv4 address doesn’t work for https (SSL). If you want a https server you can only have one server or make your setup so that the default (first) server is the only one that can have https. We can’t do anything about this, it is a protocol restriction.
Add a hard disk.
The standard virtual server setup puts the /srv directory on the root disk and this disk is standard about 7 Gb. With the virtualbox gui create a new attached hard disk to our virtual server and make it as big as you think you need. After you start the virtual machine, setup a partition with cfdisk or fdisk, create a filesystem on the new partition and mount it on /srv. Make sure you create the /srv/ftp and /srv/http directories as the were before the mount. Add this new disk to /etc/fstab. The /etc/fstab should now look like:
# # /etc/fstab: static file system information # # <file system> <dir> <type> <options> <dump> <pass> tmpfs /tmp tmpfs nodev,nosuid 0 0 devpts /dev/pts devpts defaults 0 0 shm /dev/shm tmpfs nodev,nosuid 0 0 # /dev/sda1 /boot ext2 defaults 0 2 /dev/sda2 swap swap defaults 0 0 /dev/sda3 / ext4 defaults 0 1 /dev/sdb1 /srv ext4 defaults 0 2
Now we have the same layout as if we would use the Apache web server. This is on purpose so that you can easy migrate from or to Apache.
Installation.
Install the Nginx webserver with PHP and some basic extensions, and the FastCGI Process Manager for PHP:
[root@nginx ~]# pacman -S nginx php-fpm php-gd php-mcrypt resolving dependencies... looking for inter-conflicts... Targets (11): nginx-1.0.11-1 libxml2-2.7.8-1 php-5.3.8-6 php-fpm-5.3.8-6 libpng-1.4.8-1 libjpeg-turbo-1.1.1-4 freetype2-2.4.8-1 php-gd-5.3.8-6 libmcrypt-2.5.8-3 libltdl-2.4.2-2 php-mcrypt-5.3.8-6 Total Download Size: 7.48 MB Total Installed Size: 38.56 MB Proceed with installation? [Y/n] :: Retrieving packages from core... libltdl-2.4.2-2-i686 153.6K 340.4K/s 00:00:00 [######################] 100% :: Retrieving packages from extra... libxml2-2.7.8-1-i686 1495.8K 770.5K/s 00:00:02 [######################] 100% php-5.3.8-6-i686 2.8M 979.3K/s 00:00:03 [######################] 100% php-fpm-5.3.8-6-i686 1586.8K 752.5K/s 00:00:02 [######################] 100% libpng-1.4.8-1-i686 213.8K 415.6K/s 00:00:01 [######################] 100% libjpeg-turbo-1.1.... 221.6K 466.0K/s 00:00:00 [######################] 100% freetype2-2.4.8-1-i686 568.3K 602.3K/s 00:00:01 [######################] 100% php-gd-5.3.8-6-i686 71.2K 307.9K/s 00:00:00 [######################] 100% libmcrypt-2.5.8-3-i686 67.4K 301.4K/s 00:00:00 [######################] 100% php-mcrypt-5.3.8-6... 10.3K 100.2K/s 00:00:00 [######################] 100% :: Retrieving packages from community... nginx-1.0.11-1-i686 362.5K 625.5K/s 00:00:01 [######################] 100% (11/11) checking package integrity [######################] 100% (11/11) checking for file conflicts [######################] 100% ( 1/11) installing nginx [######################] 100% Optional dependencies for nginx passenger ( 2/11) installing libxml2 [######################] 100% ( 3/11) installing php [######################] 100% ( 4/11) installing php-fpm [######################] 100% ( 5/11) installing libpng [######################] 100% ( 6/11) installing libjpeg-turbo [######################] 100% ( 7/11) installing freetype2 [######################] 100% ( 8/11) installing php-gd [######################] 100% ( 9/11) installing libmcrypt [######################] 100% (10/11) installing libltdl [######################] 100% (11/11) installing php-mcrypt [######################] 100% [root@nginx ~]#
It looks like there is no configuration needed for php-fpm, so start it:
[root@nginx ~]# rc.d start php-fpm :: Checking configuration [DONE] :: Starting php-fpm . [DONE] [root@nginx ~]#
In many examples you find on the Internet php-fpm listens to port 9000 on localhost, but on Arch Linux it uses the socket /var/run/php-fpm/php-fpm.sock. If you want, you can use TCP, it is configured in /etc/php/php-fpm.conf.
CGI scripts.
If you have a site with static content and some CGI scripts, you need to install the fcgiwrap package.
[root@nginx ~]# pacman -S fcgiwrap resolving dependencies... looking for inter-conflicts... Targets (3): fcgi-2.4.0-7 spawn-fcgi-1.6.3-2 fcgiwrap-1.0.3-2 Total Download Size: 0.06 MB Total Installed Size: 0.35 MB Proceed with installation? [Y/n] :: Retrieving packages from extra... fcgi-2.4.0-7-i686 47.3K 225.7K/s 00:00:00 [######################] 100% :: Retrieving packages from community... spawn-fcgi-1.6.3-2... 8.4K 161.3K/s 00:00:00 [######################] 100% fcgiwrap-1.0.3-2-i686 9.4K 175.6K/s 00:00:00 [######################] 100% (3/3) checking package integrity [######################] 100% (3/3) checking for file conflicts [######################] 100% (1/3) installing fcgi [######################] 100% (2/3) installing spawn-fcgi [######################] 100% (3/3) installing fcgiwrap [######################] 100% [root@nginx ~]#
The default configuration is fine, start it:
[root@nginx ~]# rc.d start fcgiwrap :: Starting fcgiwrap daemon [DONE] [root@nginx ~]#
This daemon listens on localhost to port 9001. You can change that in a socket if you want, but then you must rewrite /etc/conf.d/fcgiwrap. I personally do not find this worth the effort because CGI scripts are not commonly used. However if you have a site which has a lot of traffic via CGI scripts you might want to change the communication between fcgiwrap and nginx to a socket.
Configure nginx.
All the configuration files are in the directory /etc/nginx/conf, you only need to edit nginx.conf:
# /etc/nginx/conf/nginx.conf at nginx.wpl.uk
#
worker_processes 1;
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"';
sendfile on;
keepalive_timeout 65;
gzip on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/x-javascript text/xml ap
plication/xml application/xml+rss text/javascript;
gzip_disable "MSIE [1-6]\.";
# Upstream to abstract backend connection(s) for PHP.
upstream php {
server unix:/var/run/php-fpm/php-fpm.sock;
}
upstream cgi {
server 127.0.0.1:9001;
}
# Virtual host server www is a simple static server.
server {
listen 10.126.162.4:80 default_server;
listen [2001:1af8:fecf:7ea2::200]:80;
server_name www.wpl.uk;
root /srv/http/www;
access_log logs/www_access_log;
error_log logs/www_error_log;
location / {
index index.html;
}
}
# Virtual host server 2 is a SSI site with CGI includes.
server {
listen 10.126.162.4:80;
listen [2001:1af8:fecf:7ea2::201]:80;
server_name server2.wpl.uk;
root /srv/http/server2;
access_log logs/server2_access_log;
error_log logs/server2_error_log;
location / {
index index.html index.shtml;
ssi on;
}
# CGI scripts
location ~ ^/cgi-bin/.*\.cgi$ {
gzip off;
fastcgi_pass cgi;
include fastcgi_params;
}
}
# Virtual host server3 is a PHP application.
server {
listen 10.126.162.4:80;
listen [2001:1af8:fecf:7ea2::202]:80;
server_name server3.wpl.uk;
root /srv/http/server3;
access_log logs/server3_access_log main;
error_log logs/server3_error_log;
location / {
index index.php;
}
location ~ \.php$ {
fastcgi_pass php;
include fastcgi.conf;
}
}
}
This example shows three virtual servers, a static server, a SSI with CGI server and a PHP application server. Start nginx and test if everything works:
[root@nginx ~]# rc.d start nginx :: Checking configuration [DONE] :: Starting Nginx [DONE] [root@nginx ~]#
Download.
You can find the configuration in the examples/nginx directory in this archive:
