You are here

Install NginX and PHP with PHP-FPM, MySQL and APC

*** DISCLAIMER: All content provided here including the scripts is provided without any warranty. You use it at your own risk. I can not be held responsible for any damage that may occur because of it. By using the scripts I provide here you accept this terms.

*** Please bear in mind that this method is intended for development and testing purposes only. If you care about stability and security you should use the packages provided by your distribution.

An unattended script that installs everything can be found at GitHub. Check the README file for instructions on how to run the installer.

If you found this useful and you want to contribute, please consider sending a donation (click the button below).

In this tutorial I will compile the latest NginX (1.3.0) and PHP (5.4.3) with FPM, MySQL and APC (3.1.10) on Ubuntu Precise (12.04). For the moment, Suhosin 0.9.33 is not working with PHP 5.4.x. Apart for some version numbers for some dependencies, all the steps should be the similar for Ubuntu Lucid, Maverick, Natty and Oneiric.

I will not explain how to configure NginX here. You can find a lot of resources about that on the nginx wiki.

In order to compile these programs you will need the following dependencies (most of them should already be installed):

sudo apt-get install htop vim-nox binutils cpp flex gcc libarchive-zip-perl libc6-dev m4 libpcre3 libpcre3-dev libssl-dev libpopt-dev lynx make perl perl-modules openssl unzip zip autoconf2.13 gnu-standards automake libtool bison build-essential zlib1g-dev ntp ntpdate autotools-dev g++ bc subversion psmisc

And also some libraries for PHP:

sudo apt-get install libmysqlclient-dev mysql-client libcurl4-openssl-dev libgd2-xpm-dev libjpeg-dev libpng3-dev libxpm-dev libfreetype6-dev libt1-dev libmcrypt-dev libxslt1-dev bzip2 libbz2-dev libxml2-dev libevent-dev libltdl-dev libmagickwand-dev libmagickcore-dev imagemagick libreadline-dev libc-client-dev libsnmp-dev snmpd snmp

Now let's create a folder in which we can play:

mkdir ~/lemp
cd ~/lemp

and start downloading the sources:

wget http://nginx.org/download/nginx-1.3.0.tar.gz
wget http://us.php.net/distributions/php-5.4.3.tar.gz
wget http://pecl.php.net/get/APC-3.1.10.tgz

You can visit each site in order to find faster mirrors. Now decompress them:

tar zxvf nginx-1.3.0.tar.gz
tar xzvf php-5.4.3.tar.gz
tar xzvf APC-3.1.10.tgz

And now let's install them one by one. I like to put everything I compile by myself in one place, the /opt directory. By doing this I know where to find things like configuration files and libraries.

cd nginx-1.3.0/

./configure \
  --prefix=/opt/nginx \
  --conf-path=/etc/nginx/nginx.conf \
  --pid-path=/var/run/nginx.pid \
  --lock-path=/var/lock/nginx.lock \
  --http-log-path=/var/log/nginx/access.log \
  --error-log-path=/var/log/nginx/error.log \
  --http-client-body-temp-path=/var/lib/nginx/body \
  --http-proxy-temp-path=/var/lib/nginx/proxy \
  --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
  --http-uwsgi-temp-path=/var/lib/nginx/uwsgi \
  --http-scgi-temp-path=/var/lib/nginx/scgi \
  --with-http_stub_status_module \
  --with-http_ssl_module \
  --with-http_realip_module \
  --with-http_gzip_static_module \
  --user=www-data \
  --group=www-data \
  --without-mail_pop3_module \
  --without-mail_imap_module \
  --without-mail_smtp_module
 
make
sudo make install

cd ..
sudo wget -O /etc/init.d/nginx https://github.com/vladgh/VladGh.com-LEMP/raw/master/init_files/nginx
sudo chmod +x /etc/init.d/nginx
sudo update-rc.d -f nginx defaults

You sould also create the file /etc/logrotate.d/nginx in order to compress the logs.

sudo vi /etc/logrotate.d/nginx

And add the following lines:

/var/log/nginx/*.log {
        weekly
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
                [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
        endscript
}

You can also find a very simple configuration for nginx at https://github.com/vladgh/VladGh.com/blob/master/nginx.conf

Starting with Ubuntu 11.04 the canonical team modified the path for some libraries so you might need to run the following set of commands:

arch=$(dpkg-architecture -qDEB_HOST_MULTIARCH)
[ -f /usr/lib/${arch}/libjpeg.so ] && sudo ln -s /usr/lib/${arch}/libjpeg.so /usr/lib/
[ -f /usr/lib/${arch}/libpng.so ] && sudo ln -s /usr/lib/${arch}/libpng.so /usr/lib/
[ -f /usr/lib/${arch}/libXpm.so ] && sudo ln -s /usr/lib/${arch}/libXpm.so /usr/lib/
[ -f /usr/lib/${arch}/libmysqlclient.so ] && sudo ln -s /usr/lib/${arch}/libmysqlclient.so /usr/lib/
[ -d /usr/lib/i386-linux-gnu/mit-krb5 ] && sudo ln -s /usr/lib/${arch}/mit-krb5/lib*.so /usr/lib/

Now let's compile the PHP packages:

sudo mkdir /var/www && chown -R www-data:www-data /var/www
cd php-5.4.3

./buildconf --force

./configure \
  --prefix=/opt/php5 \
  --with-config-file-path=/etc/php5 \
  --with-config-file-scan-dir=/etc/php5/conf.d \
  --with-curl \
  --with-pear \
  --with-gd \
  --with-jpeg-dir \
  --with-png-dir \
  --with-zlib \
  --with-xpm-dir \
  --with-freetype-dir \
  --with-t1lib \
  --with-mcrypt \
  --with-mhash \
  --with-mysql \
  --with-mysqli \
  --with-pdo-mysql \
  --with-openssl \
  --with-xmlrpc \
  --with-xsl \
  --with-bz2 \
  --with-gettext \
  --with-fpm-user=www-data \
  --with-fpm-group=www-data \
  --disable-debug \
  --enable-fpm \
  --enable-exif \
  --enable-wddx \
  --enable-zip \
  --enable-bcmath \
  --enable-calendar \
  --enable-ftp \
  --enable-mbstring \
  --enable-soap \
  --enable-sockets \
  --enable-sqlite-utf8 \
  --enable-shmop \
  --enable-dba \
  --enable-sysvsem \
  --enable-sysvshm \
  --enable-sysvmsg

make
sudo make install

Because the executables are not in a standard location you can add the following lines to /etc/environment so that the new path is always loaded:

export PATH="$PATH:/opt/php5/bin:/opt/php5/sbin"
sudo echo "PATH=\"$PATH\"" > /etc/environment

The next step is to configure PHP-FPM:

sudo mkdir /var/log/php-fpm
sudo chown -R www-data:www-data /var/log/php-fpm
sudo cp -f php.ini-production /etc/php5/php.ini
sudo chmod 644 /etc/php5/php.ini
sudo cp/etc/php5/php-fpm.conf.default /etc/php5/php-fpm.conf
sudo cp -f sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
sudo chmod 755 /etc/init.d/php-fpm
sudo update-rc.d -f php-fpm defaults

If you installed these somewhere custom like me you should also modify the init file for php-fpm (/etc/init.d/php-fpm):

prefix=/opt/php5 ##(in this case only, maybe you have it somewhere else)
exec_prefix=${prefix}
php_fpm_BIN=${exec_prefix}/sbin/php-fpm
php_fpm_CONF=/etc/php5/php-fpm.conf
php_fpm_PID=/var/run/php-fpm.pid

Also, make the desired modifications to /opt/php5/etc/php-fpm.conf file. Pay attention to the pid file, socket, and dynamic processes. A sample conf file can be found here.

The newer versions of php complain if a time zone is not set on php.ini (so we grab the system's one)

TIMEZONE=$([ -f /etc/timezone ] && cat /etc/timezone | sed "s/\//\\\\\//g")
sudo sed -i "s/^\;date\.timezone.*$/date\.timezone = \"${TIMEZONE}\" /g" /etc/php5/php.ini

Create /etc/logrotate.d/php-fpm with the following:

/var/log/php-fpm/*.log {
        weekly
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 www-data www-data
        sharedscripts
        postrotate
                [ ! -f /var/run/php-fpm.pid ] || kill -USR1 `cat /var/run/php-fpm.pid`
        endscript
}

Now let's install the latest APC:

cd ../APC-3.1.10
/opt/php5/bin/phpize -clean
./configure --enable-apc --with-php-config=/opt/php5/bin/php-config --with-libdir=/opt/php5/lib/php
make
sudo make install

You will have to add the extension in php.ini:

sudo mkdir /etc/php5/conf.d

sudo echo 'extension = apc.so
apc.enabled = 1
apc.shm_size = 128M
apc.shm_segments=1
apc.write_lock = 1
apc.rfc1867 = On
apc.ttl=7200
apc.user_ttl=7200
apc.num_files_hint=1024
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.enable_cli=1
; Optional, for "[apc-warning] Potential cache slam averted for key... errors"
; apc.slam_defense = Off
'
> /etc/php5/conf.d/apc.ini

This is it! You can now start the servers:

/etc/init.d/php-fpm start
/etc/init.d/nginx start

If you want a MySQL server installed you can run the following command.

apt-get install mysql-server mysql-client

This should be enough to get MySQL up and running. If you have a separate database somewhere you can only install the mysql-client package. For additional config parameters look into the /usr/share/doc/mysql-server-5.1/examples folder and you will find a few configurations. You can also get the MySQLTuner.pl script which will give a lot more information on how to fine tune your mysql server:

wget mysqltuner.pl

You should now have a fully functional LEMP platform.

An unattended script that installs everything can be found at GitHub. Check the README file for instructions on how to run the installer.


If you found this useful and you want to contribute, please consider sending a donation (click the button below).

Comments

I wanted to say thank you for writing this up. It really helped me to get nginx running with php-fpm which I was having trouble doing after reading about 20 other write-ups as well as spending hours of wasted time trying to figure it out on my own, which just did not work. Thanks again!
Vlad's picture

I tried them all, and after failing so many times, I compiled everything by myself.

when i try to start php fpm i get: [ALERT] [pool www] pm.min_spare_servers(0) must be a positive value Aug 20 16:46:39.110439 [ERROR] failed to post process the configuration
Vlad's picture

I have the following working configuration on a 512MB RAM machine:

pm.max_children = 20
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500

So just do as the error said: increase the number of min_spare_servers. Also I think the number of start servers needs to be equal or greater than max_spare_servers.

Can i install solr also from you previous guide http://vladgh.com/blog/apache-solr-tomcat-6-and-drupal-ubuntu-1004 after I install NginX and PHP 5.3.3 with PHP-FPM, MySQL and APC?
Vlad's picture

Of course you can.

I finally installed everything, started every process but there's no way to parse php i guess.

in my nginx.conf

location ~ .php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name; #also tried with /html$fastcgi_script_name;
            include        /opt/nginx/conf/fastcgi_params;
        }

on the browser i see only The page you are looking for is temporarily unavailable.
Please try again later., wich is the 50x.html

Vlad's picture

First of all check the php-fpm.conf file to see if it is listening on a socket or tcp:

;listen = 127.0.0.1:9000
listen = /var/run/php-fpm.sock

If you used my example attached to this article it'a a socket so your it should be:
fastcgi_pass unix:/var/run/php-fpm.sock
Or whatever your sock file is...
If not you can check the location regexp, and change it into location ~ \.php$ (Maybe the dot needs to be escaped).
Then you can try using absolute paths, so instead of just html, something like /opt/nginx/html.

Vlad, thanks for writing this tutorial! I am having an issue getting PHP-FPM to start. When I run the 'sudo /etc/init.d/php-fpm start' command it stalls and then fails. It says... Starting pfp-fpm ................................ failed.
Vlad's picture

You have to either set the right permissions for your .pid file and/or .sock, or to adjust the init file (/etc/init.d/php-fpm) to include the corect paths to the fpm files:

prefix=/opt/php5 ##(in this case only, maybe you have it somewhere else)
exec_prefix=${prefix}
php_fpm_BIN=${exec_prefix}/sbin/php-fpm
php_fpm_CONF=${prefix}/etc/php-fpm.conf
php_fpm_PID=/var/run/php-fpm.pid

Pages

Add new comment

Recent comments