If you are interested, like I am, in setting up your own web server and hosting your own projects then I hope you will follow along. This guide will walk you step by step on setting up a LEMP stack (Linux, Nginx, MySQL, and PHP).
Getting Started
I will be installing the required packages on Ubuntu 10.04 LucidLynx LTS. Additionally, I’ve had great success using Rackspace Cloud Servers, they are easy to setup and use (like this one, most of my linux based guides will use a Rackspace Cloud Server as a starting point). I will assume you have your server all setup, and you are ready to begin at the command line, so lets get started:
First, for good measure lets make sure our server is all up-to-date.
apt-get update
Installing MySQL
Then let’s begin by installing MySQL:
apt-get install mysql-server mysql-client
after entering the above command you will also be prompted for a MySQL “root” user password…
Installing PHP
Next up, lets install PHP5 and a few common extensions (here is a list if you are in need of other extensions):
apt-get install php5-cgi php5-cli php5-mysql php5-curl php5-gd php5-idn php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-mhash php5-pspell php5-recode php5-sqlite php5-tidy php5-xmlrpc php5-xsl
As you may have noticed, we have installed php-cgi
, that is because we will be running a FastCGI interface.
There are some articles online which recommend using lighttpd for its FastCGI interface, this is totally not needed. PHP has its own FastCGI interface which works perfectly well (thanks to Tomasz Sterna for a great article on FastCGI with Nginx)
At this point, we will be using a little bit of vim
to do a bit of file editing, so here is a quick primer on using vim
.
Lets create the following file: /etc/init.d/php-fastcgi
vim /etc/init.d/php-fastcgi
This file will have the following content:
#!/bin/bash BIND=127.0.0.1:9000 USER=www-data PHP_FCGI_CHILDREN=5 PHP_FCGI_MAX_REQUESTS=500 PHP_CGI=/usr/bin/php-cgi PHP_CGI_NAME=`basename $PHP_CGI` PHP_CGI_ARGS="- USER=$USER PATH=/usr/bin PHP_FCGI_CHILDREN=$PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS=$PHP_FCGI_MAX_REQUESTS $PHP_CGI -b $BIND" RETVAL=0 start() { echo -n "Starting PHP FastCGI: " start-stop-daemon --quiet --start --background --chuid "$USER" --exec /usr/bin/env -- $PHP_CGI_ARGS RETVAL=$? echo "$PHP_CGI_NAME." } stop() { echo -n "Stopping PHP FastCGI: " killall -q -w -u $USER $PHP_CGI RETVAL=$? echo "$PHP_CGI_NAME." } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; *) echo "Usage: php-fastcgi {start|stop|restart}" exit 1 ;; esac exit $RETVAL
As Tomasz Sterna mentions, you will need to fiddle with the PHP_FCGI_CHILDREN
and PHP_FCGI_MAX_REQUESTS
variables depending on your server’s amount of memory and compute power. I am running a baseline 256 MB / 10 GB Rackspace Cloud Server so I use the following settings which seem to work very well (as seen above):
PHP_FCGI_CHILDREN=5 PHP_FCGI_MAX_REQUESTS=500
Moving on … after you’ve created and saved the file we will make it executable and then start up the FastCGI service with the following commands:
chmod +x /etc/init.d/php-fastcgi /etc/init.d/php-fastcgi start
We will want the service to auto start when we reboot our server, so we also do the following:
update-rc.d php-fastcgi defaults
Installing Nginx
Installing Nginx is easy, use the following commands to install and then start up the Nginx server.
apt-get install nginx /etc/init.d/nginx start
After installing Nginx, it will be automatically configured to start when we reboot our server (unlike the PHP FastCGI service we had to setup), so we are all set.
Testing Nginx and PHP
At this point we can see that Nginx is working by typing the server’s IP address into a web browser (http://[IP_ADDRESS]/
). You should get a “Welcome to nginx!” message.
Now lets test PHP, we will create a generic phpinfo.php
file with the following:
echo "<?php phpinfo(); ?>" > /var/www/nginx-default/phpinfo.php
/var/www/nginx-default/
is the Nginx server default root directory…
If you use your browser to go to http://[IP_ADDRESS]/phpinfo.php
,you will notice that it doesn’t work … before this will work, we have to enable FastCGI in the Nginx config file. Open up the following file:
vim /etc/nginx/sites-available/default
Find the following lines (scroll to line 47):
#location ~ \.php$ { #fastcgi_pass 127.0.0.1:9000; #fastcgi_index index.php; #fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; #includefastcgi_params; #}
and change them to (removing the #
character from each line, changing line 50 and adding a space between include
and fastcgi_params
on line 51):
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/nginx-default/$fastcgi_script_name; include fastcgi_params; }
Now lets restart Nginx so our config changes will take effect:
/etc/init.d/nginx restart
Now use your web browser to go to http://[IP_ADDRESS]/phpinfo.php
, you should see a PHP info page similar to the following:
I use “Nginx” + “PHP5-fpm” and not “php-fastcgi” because it is faster… than create a php-fastcgi process and quit this process for every php-data… my howto -> http://suckup.de/blog/2010/07/31/nginx-php5-fpm-auf-debianubuntu/ (only in German, but there is a example)
voku, thanks for the link, i am looking into using php fpm, but I am unable to find any documentation on efficiently running php under a specific uid/gid for a multi user virtual host environment.
I have make it this way ->
http://michaelshadle.com/2010/08/26/cleanest-configuration-for-the-new-php-fpm/
Info: http://wiki.nginx.org/NginxFaq#What_about_support_for_something_like_mod_suexec.3F
PS: you can also activate chroot for php-fpm… if you want protect other websites…
PHP’s FastCGI does not spawn a separate process for every processed request. This is how CGI works and FastCGI was designed to mitigate this.
The variable PHP_FCGI_MAX_REQUESTS says how many requests will a single php-cgi process serve before quitting. After that the process quits and another one is spawned (keeping up to PHP_FCGI_CHILDREN parallel processes at any time).
I got this error on line 48…..any idea why that might be? Cheers
/etc/init.d/nginx restart
Restarting nginx: [emerg]: “fastcgi_pass” directive is not allowed here in /etc/nginx/sites-enabled/default:48
configuration file /etc/nginx/nginx.conf test failed
Hi
Thanks u admin. Very nice article.
“service php-fastcgi start”
When I run the error is
Error Text:
Starting PHP FastCGI: /etc/init.d/php-fastcgi: line 14: start-stop-daemon: command not found
php-cgi.
This installation helped me set-up a fully functional server. A thumbs up to the author!
For me, the line
echo “” > /var/www/nginx-default/phpinfo.php[\code]
doesn’t work. The directory does not exist. In the settings file , the line
root /usr/share/nginx/www;[\code] can be found.
I’m a noob, but it seems to me that the root directory has moved. (Version 1.1.19
My default nginx website was installed to /usr/share/nginx/www/