As mentioned previously, I’ve recently moved this domain over to Slicehost. What follows is Part Two of a guide, compiled from my notes, to setting up an Ubuntu Hardy VPS. See also Part One, Part Three, Part Four.
Now we’ve got a properly configured, but idle, box. Let’s do something with it.
Nginx is a small, lightweight web server that’s all the rage on some small corners of the Net. Apache is extremely overkill for a small personal web server like this and, since we’re limited to 256MB of RAM on this VPS, it quickly becomes a resource hog. Lighttpd is another small, lightweight web server, but I’m a fan of Nginx. Try it out.
First, we need to install the web server. Nginx is now in Ubuntu’s repositories:
$ sudo aptitude install nginx
That’s all it takes in Hardy, but if you really want a guide for it, Slicehost has you covered.
Slicehost has a few more useful guides to Nginx, including introductions to the config layout and how to get started with vhosts:
Next up, we’ll need to install MySQL and PHP, and get them working with Nginx.
Slicehost has a guide for installing MySQL and Ruby on Rails, which also includes suggestions on optimizing MySQL. I follow the MySQL part of the guide, stopping at “Ruby on Rails install”.
Now MySQL is working, lets install PHP:
$ sudo aptitude install php5-common php5-cgi php5-mysql php5-cli
To get PHP as FastCGI working with Nginx, we first have to spawn the fcgi process. There are a few different ways to do that. Personally, I use the spawn-fci app from lighttpd. To use it, we’ll compile and make lighttpd, but not install it. We’re only after one binary.
Lighttpd has a few extra requirements, so let’s install those:
$ sudo aptitude install libpcre3-dev libbz2-dev
Now, download the source and compile lighttpd. Then copy the spawn-fci binary to /usr/bin/:
$ wget http://www.lighttpd.net/download/lighttpd-1.4.19.tar.gz $ tar xvzf lighttpd-1.4.19.tar.gz $ cd lighttpd-1.4.19 $ ./configure $ make $ sudo cp src/spawn-fcgi /usr/bin/spawn-fcgi
Then, create a script to launch spawn-fci (I call it /usr/bin/php5-fastcgi):
#!/bin/sh /usr/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -u www-data -C 2 -f /usr/bin/php5-cgi
The script tells spawn-fcgi to launch a fastcgi process, listening on 127.0.01:9000, owned by the web user, with only 2 child processes. You may want more child processes, but I’ve found 2 to be optimal.
Give the script permissions:
$ sudo chmod +x /usr/bin/php5-fastcgi
I then link the script filename to a version-neutral, err, version:
$ sudo ln -s /usr/bin/php5-fastcgi /usr/bin/php-fastcgi
Now we need an init script to start the process at boot. I use this one from HowToForge, named /etc/init.d/fastcgi:
#!/bin/bash
PHP_SCRIPT=/usr/bin/php-fastcgi
RETVAL=0
case "$1" in
start)
echo "Starting fastcgi"
$PHP_SCRIPT
RETVAL=$?
;;
stop)
echo "Stopping fastcgi"
killall -9 php5-cgi
RETVAL=$?
;;
restart)
echo "Restarting fastcgi"
killall -9 php5-cgi
$PHP_SCRIPT
RETVAL=$?
;;
*)
echo "Usage: php-fastcgi {start|stop|restart}"
exit 1
;;
esac
exit $RETVAL
Give it permissions:
$ sudo chmod 755 /etc/init.d/fastcgi
Start it:
$ sudo /etc/init.d/fastcgi start
Have it start at boot:
$ sudo update-rc.d fastcgi defaults
Alright, now that PHP is running how we want it to, let’s tell Nginx to talk to it. To do that, add the following to your vhost server block in /etc/nginx/sites-available/mydomain.com, making sure to change the SCRIPT_FILENAME variable to match your directory structure:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/user/public_html/mydomain.com/public$fastcgi_script_name;
include /etc/nginx/fastcgi.conf;
}
Now let’s create that /etc/nginx/fastcgi.conf file that’s being included above. As per the Nginx wiki article, mine looks like this:
fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx; 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 REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; 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;
Then restart Nginx:
$ sudo /etc/init.d/nginx restart
Let’s create a file named test.php in your domain’s public root to see if everything is working. Inside, do something like printing phpinfo.
Go to http://mydomain.com/test.php. See it? Good. If you get “no input file specified” or somesuch, you broke something.
If you create an index.php, and delete any index.html or index.htm you might have, you’ll notice Nginx throws a 403 Forbidden error. To fix that, find the line in your vhost config (/etc/nginx/sites-available/mydomain.com) under the location / block that reads index index.html; and change it to index index.php index.html;. Then restart Nginx.
If you want SSL with your Nginx, Slicehost has a guide for generating the certificate and another guide for installing it.
You’ll want to install OpenSSL first:
$ sudo aptitude install openssl
There is one bug in the second guide. In the first server module listening on port 443, which forwards www.domain1.com to domain1.com, the rewrite rule specifies the http protocol. So, in effect, what that rule does is forward you from a secure domain to unsecure: https://www.domain1.com to http://domain1.com. We want it to forward to a secure domain. Simply change the rewrite rule like thus:
rewrite ^/(.*) https://domain1.com permanent;
Next up: install a mail server. (Previously, we did a basic setup.)





Hi,
Thank you very much for your tutorial. I ask how to install and configure PhpMyAdmin to run under all vhosts, with only one installation.
Can you help ?
Tanks
Carlo
Noticed a slight flaw in your instructions. In the bit about compiling Lighthttpd, cd lighttpd-1.4.18.tar.gz
should be replaced with cd lighttpd-1.4.19
@ Carlo:
I don’t use phpmyadmin, but you should be able to just install it in one directory, then put an alias under the server block of each of your vhosts in your nginx config, as Slicehost explains in this article under the “alias” heading. Another option would be to symlink it from one directory to the public html folder of each of your vhosts.
@ Kevin:
Thanks! Fixed.
Hi,
I know You cannot help me without specific infos, but I try anyway excuse me.
Well … I followed all your instructions:
1) I installed Nginx web server, mysql and php
2) I configured Nginx and vhost following SliceHost guides
3) I installed spawn-fcgi and I followed all your info (by copy and paste into my SSH connection)
4) I restart (well … stop and start) Nginx
5) I create a index.php file that I put in /home/zenobox/public_html/evaskiva.com/public
I’m so sure to complete all procedure in a correct way.
But when I point my browser on http://www.evaskiva.com/index.php (or without index.php) the reposne is 404 not found … try yourself …
The server is running try http://209.20.69.80/
What can I make wrong ?
I know it’s not easy but can you help me ?
Thanks
Care to post (or email me if you don’t want it public) your nginx server block for the vhost?
No problem, you are very kindly …
Vhost is:
server {
listen 80;
server_name http://www.evaskiva.com;
rewrite ^/(.*) http://evaskiva.com permanent;
}
server {
listen 80;
server_name evaskiva.com;
access_log /home/zenobox/public_html/evaskiva.com/log/access.log;
error_log /home/zenobox/public_html/evaskiva.com/log/error.log;
location / {
root /home/zenobox/public_html/evaskiva.com/public/;
index index.php index.html index.htm;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/zenobox/public_html/evaskiva.com/public$fastcgi_script_name;
include /etc/nginx/fastcgi.conf;
}
}
Bye
Carlo
It looks like you don’t have an index.php, which is why trying to go to it results in the 404 error. You have an index.html. That’s why going to the domain without specifying a file takes you to the index.html, even though in the nginx config you specify index.php before index.html on the index line.
Hi,
I wrote an email by your contact form, please read it.
Bye
Carlo