For PHP developers, the ideal stack is Linux, Apache, MySQL and PHP (a LAMP server). However, being a Ruby developer, I tend to prefer Nginx over Apache, as well as Postgres over MySQL, but that’s another post.
Nginx is gaining against IIS and Apache because it’s very good at being a web server and uses fewer resources to do its job. And serving PHP with Nginx is easy to do, too. While most guides use custom FastCGI spawners and scripts, serving PHP with Nginx can be done even quicker and easier with mostly apt-get
installed software.
Note: This was written for Ubuntu 12.04 and PHP 5.
First get the Nginx signing key so the server can trust the download and install the software provided by nginx.org.
wget http://nginx.org/keys/nginx_signing.key
apt-key add nginx_signing.key
rm nginx_signing.key
Add the nginx repo to /etc/apt/sources.list.d
.
echo "deb http://nginx.org/packages/ubuntu precise nginx" > /etc/apt/sources.list.d/nginx.list
Note: I’m on Ubuntu 12.04 LTS, so I’m using “precise”. At the time of this writing, there is also “lucid”, “oneiric” and “quantal” builds available. Use the server’s version of Ubuntu in the command instead.
Then update the sources list and install Nginx.
apt-get update && apt-get install nginx
Instead of a custom spawner and init.d
script, this setup will be based on PHP-FPM, which is “a simple and robust FastCGI Process Manager for PHP.”
apt-get install php5-cli php5-cgi psmisc spawn-fcgi php5-fpm
Edit the file /etc/php5/fpm/pool.d/www.conf
so php-fpm will use a UNIX socket instead of a TCP/IP connection.
Look for listen = 127.0.0.1:9000
and change it to listen = /tmp/php5-fpm.sock
.
The application might require some additional PHP extensions to be fully functional. I tend to install the following extensions because they are required by a few big applications like Wordpress and ownCloud.
apt-get install php5-gd php-xml-parser php5-intl php5-curl
Just for the sake of installing a complete stack (a LEMP server), MySQL is very easy to install. However, it might need some tweaking depending on the specs of the server and application needs.
apt-get install mysql-client mysql-server php5-mysql libmysqlclient-dev
mysql_secure_installation
Before hooking everything up, I want show how I setup the default directory structure for most of PHP or static file projects to give some context to the Nginx config and the symbolic linking commands.
/home/deploy/apps
|-- example.com # project name
|-- public # web accessible directory
|-- info.php # file for testing install
|-- config
|-- nginx.conf # server config file
The content of info.php
:
<?php phpinfo(); ?>
The content of nginx.conf
:
server {
listen 80;
server_name example.com;
root /home/deploy/apps/example.com/public;
index index.html index.php;
client_max_body_size 1G;
fastcgi_buffers 64 4K;
location / {
try_files $uri $uri/ index.php;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/tmp/php5-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Nginx comes setup for multiple hosts out of the box. The configurations for available websites are in /etc/nginx/conf.d/
. Start by deleting the default Nginx server.
rm /etc/nginx/conf.d/default.conf
Then link up the new project
ln -s /home/deploy/apps/example.com/config/nginx.conf /etc/nginx/conf.d/example.com.conf
Restart Nginx
service nginx restart
The system parameters of the PHP install should be available at http://example.com/info.php
. A caveat, though, is this is a quick way to serving PHP and some security precautions were taken, such as:
mysql_secure_connection
try_files $uri =404;
to the Ninx server configHowever, there is always more that can be done to secure a server.