§ The 5-minute LAMP Stack
With the release of
Debian 7.0 "Wheezy", PHP 5.4 is available though apt-get from the word go.
This means it now only takes a few minutes to setup a lightweight web server capable of dealing with
the latest web applications with very little configuration. I use the term
LAMP loosely in this article because
it's easier to pronounce than LNMP.
My usual requirements for a web server are as follows:
- NGINX 1.2+
- PHP-FPM 5.4+
- MySQL 5+
- An SMTP Server (I don't need a full-blown mail server)
These are now all available in the Wheezy repositories, so all we need are a few commands.
Firstly, for a fresh build you'll want to get the basics right:
apt-get install vim htop ntp nscd
echo "your.fullyqualified.hostname" > /etc/hostname
hostname -F /etc/hostname
dpkg-reconfigure tzdata
Grab the LAMP packages:
apt-get install nginx php5-cli php5-fpm php5-mysqlnd php5-xcache php5-curl mysql-server mysql-client
This is always good practice for your MySQL server:
mysql_secure_installation
Setup SMTP, see Linode's simple guide for step-by-step instructions on the second command here:
apt-get install exim4-daemon-light mailutils
dpkg-reconfigure exim4-config
Now let's lockdown the server a bit, you may like to use this gist as a base for your firewall rules - be sure to read through them though or you'll lock yourself out:
apt-get install iptables-persistent fail2ban
vim /etc/iptables/rules.v4 # Add your rules to this file
service iptables-persistent restart
Time to wire PHP-FPM and NGINX together:
# Disable fix_pathinfo
sed -i "s/^;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/" /etc/php5/fpm/php.ini
# Tell FPM to use TCP
sed -i "s/^listen = \/var\/run\/php5-fpm.sock/listen = 127.0.0.1:9000/" /etc/php5/fpm/pool.d/www.conf
sed -i "s/^;listen.allowed_clients/listen.allowed_clients/" /etc/php5/fpm/pool.d/www.conf
service php5-fpm restart
mkdir /etc/nginx/global
Create the file /etc/nginx/global/fpm.conf and use the following for it's contents:
location ~*\.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
fastcgi_pass 127.0.0.1:9000;
}
Nearly there, create your server block in /etc/nginx/sites-available/your-domain.com:
server {
listen 80;
server_name your-domain.com;
root /var/www/your-domain.com;
index index.php;
include /etc/nginx/global/fpm.conf;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
}
Finally, symlink your configuration file and reload NGINX:
ln -s /etc/nginx/sites-available/your-domain.com /etc/nginx/sites-enabled/your-domain.com
service nginx reload
That's it! As long as your DNS is pointing in the right place you should be good to go.
The setup above has been designed to give decent performance for PHP web applications. The
htop binary gives a much nicer view of resource usage, whilst
ntp keeps your clock in sync and nscd will cache DNS queries made
by your web applications.
The PHP Fast-CGI Process Manager allows the web server to delegate
run-time compilation of your PHP scripts to a separate process, unlike mod_php5
for Apache. The MySQL Native Driver for PHP is the recommended option above
mysqli and is part of the PHP core. Xcache will give you opcode caching, you
could also use APC or Zend Opcache.
Hopefully all of the above will result in decreased server load, latency and maximise
throughput on your server by making the most of the available resources.
§ Building a Xen Hypervisor
Wikipedia states that a hypervisor or virtual machine manager (VMM)
is a piece of software, firmware or hardware that creates and runs
virtual machines
.
I started off by reading about which operating systems were best suited to
what I would've called the Xen host. I now know the correct terminology to
be "Domain 0" or dom0 – as hypervisor terminology dictates that each
machine is a domain (including the host). It seems you can run Xen on a variety
of Linux distributions but I noticed quite a bit of documentation and articles
focusing on Debian. For this reason I picked Debian Squeeze.
The primary hard drive on my target system is 120 GiB, this doesn't leave much
room for the VMs. Luckily the Xen wiki
recommends LVM which is trivial to setup using
the Debian OS installer during dom0 creation. With the LVM partition in place on the drive I can
easily grow and shrink partitions as requirements for each virtual machine
changes over time. This allows me to make the most of what little space I have
available on the drive.
Initial installation and configuration of Xen with Xen Tools can be done by
following the guide on the Debian wiki.
One concern that struck me was that VMs would be able to access my home LAN as
everything is connected to the same router. To solve this issue I setup four LAN subnets and 802.1q
VLAN tagging in order to create network segregation. The following steps are
not required to setup Xen, they just happen to suite my particular network
setup and requirements.
Setup the VLANs on your router and make note of the tag IDs (10, 20, 30
and 40 in my case).
Enable the 802.1q kernel module and make it permanent:
modprobe 8021q && echo '8021q' >> /etc/modules
Once you've done that you'll need to install the vlan package:
apt-get install vlan
Setup the /etc/network/interfaces with as many of the above VLANs as you
require for the dom0 and domUs, here's mine (shortened for display):
# The local loopback interface
auto lo
iface lo inet loopback
# Instruct all interfaces to startup automatically
auto eth0
auto eth0.20 xenbr20
# The only physical interface (Ethernet Port 0)
iface eth0 inet dhcp
# VLAN ID: 20
iface eth0.20 inet manual
vlan_raw_device eth0
# The Xen Bridge allowing VMs to access VLAN 20
iface xenbr20 inet static
address 10.0.2.2
netmask 255.255.255.0
gateway 10.0.2.1
bridge_ports eth0.20
bridge_stp on
bridge_maxwait 10
In order to give the VMs within the VLANs internet access you'll need to
enable IPv4 forwarding and NAT on dom0:
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 'net.ipv4.ip_forward=1' > /etc/sysctl.conf
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Ensuring that iptables retains these rules on boot:
apt-get install iptables-persistent
iptables-save > /etc/iptables/rules
With all of this setup you can begin creating VMs. Here's an example using
xen-tools to create a VM with hostname 'newvm':
xen-create-image --hostname=newvm \ # Each domU should have a different hostname
--memory=256mb \
--vcpus=1 \
--lvm=vg0 \ # Specify Logical Volume Group within LVM
--dhcp \ # Allow DHCP
--pygrub \
--dist=squeeze \ # Setting the distribution to Debian Squeeze
--passwd # Prompt for root password during creation
Here's a quick bash script that makes it easy to delete VMs:
#!/bin/bash
[ -z $1 ] && { echo "Specify hostname!"; exit 1; }
xm destroy $1
xm delete $1
xen-delete-image --lvm vg0 $1 # You may wish to change the LVM group here
Incidently, LVM has an excellent snapshot feature which I've wrapped up into
this gist.
§ A Website in a Single HTTP Request
This website has no assets. There are no CSS files, no external JavaScript
sources files, no backend scripting engine and no database storage system. It's
just one HTML file and that's it. I've decided to get back to basics with my
personal site; maybe because I spend my working life optimising complex
systems, it's a sort joyful escape.
There's something about plain text that's always appealed to me. Besides
character encoding there's not much really to worry about. I know what I'm
typing now will display correctly on your laptop/phone/tablet, regardless of
your browser – because there isn't really anything to go wrong. I guess
it's like my first car in a way, forget about the electric windows, heated
windscreen and all those other fancy gadgets and you still have a car.
I must admit that resisting the temptation to use CSS3 transitions or pure
JavaScript to spice up the interactivity layer is somewhat difficult. It does
however provide a nice clean scope for the design. Either I can achieve it with
raw HTML and a couple of lines of CSS or I'm simply not going to implement it
here. I want to focus on the content of this site, I want to share what I'm
learning as it's happening. Designing the next-best has been on my to-do list
for too long.
All content on this site is free to share, just like the web should be.