Ubuntu. Development Environment with Nginx+PHP5.3+FPM+MySQL
васяц and I were setting up a development environment on our netbooks over the weekend and decided to use PHP 5.3 and PHP-FPM. I decided to install everything in the simplest way possible, so I turn to apt-get first, and only then to building from source. By the way, if you already have any version of PHP installed, remove it first (including libapache2-mod-php5, if you have it).
These instructions also apply to FreeBSD; just use installation from ports instead of “apt-get install”.
Adding a user
First, let’s create the www user and group that Nginx and PHP will run under.
addgroup www
adduser --shell /usr/sbin/nologin --no-create-home --ingroup www --disabled-password --disabled-login www
Installing Nginx
As I said, we’ll take the simplest route:
apt-get install nginx
Now let’s edit /etc/nginx/nginx.conf and add an upstream for php-fpm:
user www www;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
access_log /var/log/nginx/access.log;
sendfile on;
keepalive_timeout 65;
tcp_nodelay on;
upstream php-fpm {
#server 127.0.0.1:9000;
server unix:/tmp/php-fpm.sock;
}
include /etc/nginx/conf.d/*.conf;
}
Now let’s move on to installing PHP.
Installing PHP 5.3 + PHP-FPM
To build php 5.3 + php-fpm, we’ll need to download the php-fpm 5.3 source, but first make sure your version of autoconf is 2.13. People say other versions cause problems. I tried building with a newer version (autoconf 2.59, I think)—and yes, there really are problems. So we’ll install 2.13 specifically:
apt-get install autoconf2.13
Now we need to install bison:
apt-get install bison
Next, libevent from source. Specifically, version 1.4.13 (the older version I had installed wasn’t suitable).
There was a problem while installing libevent—libtoolize was missing… Let’s install libtool first:
apt-get install libtool
And now libevent:
wget http://www.monkey.org/~provos/libevent-1.4.13-stable.tar.gz
tar -xzvf libevent-1.4.13-stable.tar.gz
cd libevent-1.4.13-stable
./autogen.sh
./configure
make install
All versions of libevent are here.
And finally, let’s build libxml:
wget ftp://xmlsoft.org/libxml2/libxml2-2.7.6.tar.gz
tar -xzvf libxml2-2.7.6.tar.gz
cd libxml2-2.7.6
./configure
make && make install
You may need mysql_config, for example for Sphinx or the MySQL module for PHP; if so, install libmysqld-dev:
apt-get install libmysqld-dev
Now, at last, let’s download php-fpm and run the build script:
svn co http://svn.php.net/repository/php/php-src/branches/PHP_5_3_FPM php_5_3_fpm
cd php_5_3_fpm
./buildconf
We now have ./configure, and we can specify which options to build PHP with:
./configure --prefix=/usr/local --disable-short-tags --enable-fpm --with-layout=GNU --without-pear \
--enable-mbstring --with-mysql=/usr/bin/mysql_config --with-mysqli=mysqlnd
make && make install
You can read about some PHP options here, and for extensions such as mysqli/mbstring and others, check the “Installation” section of the official documentation, for example mbstring or mysqli.
Many options are enabled by default; you can change this with --disable-all.
Since I installed it in a custom directory, I’ll create a link to my php for convenience:
ln -s /usr/local/bin/php /usr/bin/php
We’ll need a script to control php-fpm, so let’s copy it from the source:
cp php_5_3_fpm/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
chmod +x /etc/init.d/php-fpm
I previously had PHP 5.2.10 installed (from packages), so I still had a php.ini, and I copied it:
cp /etc/php5/apache2/php.ini /usr/local/etc/php.ini
If you don’t know where to put your php.ini, open phpinfo, look at “Configuration File (php.ini) Path”, and put your php.ini there. On restarting, PHP reported some options as deprecated, so I simply commented them out. If you don’t have a php.ini file, you can use mine. There’s nothing special in it; it’s just in case you don’t have this file.
Configuring PHP-FPM
Let’s copy the default config:
cp /usr/local/etc/php-fpm.conf.default /usr/local/etc/php-fpm.conf
And tidy it up a little:
Address to accept fastcgi requests on.
Valid syntax is 'ip.ad.re.ss:port' or just 'port' or '/path/to/unix/socket'
<!--<value name="listen_address">127.0.0.1:9000</value>-->
<value name="listen_address">/tmp/php-fpm.sock</value>
....
<value name="listen_options">
Set listen(2) backlog
<value name="backlog">-1</value>
Set permissions for unix socket, if one used.
In Linux read/write permissions must be set in order to allow connections from web server.
Many BSD-derrived systems allow connections regardless of permissions.
<value name="owner">www</value>
<value name="group">www</value>
<value name="mode">0666</value>
</value>
...
<value name="php_defines">
<!-- <value name="sendmail_path">/usr/sbin/sendmail -t -i</value> -->
<value name="display_errors">1</value>
<value name="error_log">/var/log/php-error.log</value>
<value name="log_errors">true</value>
</value>
...
Unix user of processes
<value name="user">www</value>
Unix group of processes
<value name="group">www</value>
...
Comma separated list of ipv4 addresses of FastCGI clients that allowed to connect.
Equivalent to FCGI_WEB_SERVER_ADDRS environment in original php.fcgi (5.2.2+)
Makes sense only with AF_INET listening socket.
<value name="allowed_clients">127.0.0.1</value>
Briefly, here’s what we’re changing:
1. Use a Unix socket rather than TCP
2. Set the user and group to www
3. Send errors to the standard stream and specify the error log file
I’ve already posted this config here.
Problems with MySQLi
MySQLi complained that it couldn’t open the MySQL socket at “/tmp/mysql.sock”. I found the socket path in “/etc/my.cnf”, copied it, and corrected the path in “/usr/local/etc/php.ini”:
mysqli.default_socket = /var/run/mysqld/mysqld.sock
Starting our application server
Let’s add a virtual host to Nginx:
server {
listen 80;
server_name test.loc;
root /www/test/htdocs;
location / {
index index.php;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php-fpm;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
And start our server:
service mysql start
service nginx start
service php-fpm start
As always, it’s all simple! :)
Comments are closed. Read the original discussion in Russian →
