Categories
Generally Sysadmin

Installing the final PHP 7 as a php-fpm module on a Ubuntu 14.04 LTS system.

A view months late, the PHP community finally released the final version of PHP 7. Planned on October the final Version is now available for Download via Github. Because there are no official packages to be installed for Debian or Ubuntu at the moment, we’ll create a PHP 7 php-fpm module by compiling the source code ourselves. That will also allow us to continue having PHP5 on our server as the main version but use PHP7 to test our projects for compatibility.

For a first glimps of the new features and changes of PHP 7 I suggest reading the following article form the Zend Homepage: Coolest PHP 7 Features

1. Download

The most recent source code is available via the official Git Repository. Instead we will use the first Beta Version from the PHP Servers for now.

cd /usr/local/src
wget https://github.com/php/php-src/archive/php-7.0.0.tar.gz
tar -jxf php-7.0.0.tar.gz
cd php-src-php-7.0.0

The source code was now downloaded and extracted and we changed into the new directory.

2. Configure the source code

We’ll need a lot of support packages to compile the code successfully. With the following commands all of the needed modules should be installed.

sudo aptitude build-dep php5
sudo apt-get install libc-client2007e-dev libmcrypt-dev openssl courier-imap libgmp-dev checkinstall

With the PHP source code from git, we’ll have to create some additional files first:

./buildconf --force

Now we can configure the source code.

./configure --prefix=/opt/php7 \
--with-config-file-path=/etc/php7 \
--with-config-file-scan-dir=/etc/php7/conf.d \
--disable-short-tags \
--enable-mbstring \
--enable-zip \
--enable-bcmath \
--enable-pcntl \
--enable-ftp \
--enable-exif \
--enable-calendar \
--enable-sysvmsg \
--enable-sysvsem \
--enable-sysvshm \
--enable-wddx \
--with-curl \
--with-mcrypt \
--with-iconv \
--with-gmp \
--with-pspell \
--with-gd \
--with-jpeg-dir=/usr \
--with-png-dir=/usr \
--with-zlib-dir=/usr \
--with-xpm-dir=/usr \
--with-freetype-dir=/usr \
--enable-gd-native-ttf \
--enable-gd-jis-conv \
--with-openssl \
--with-imap \
--with-imap-ssl \
--with-pdo-mysql=/usr \
--with-gettext=/usr \
--with-zlib=/usr \
--with-bz2=/usr \
--with-kerberos \
--with-mysqli=/usr/bin/mysql_config \
--enable-fpm

Known issues during the configuration process

Error: configure: error: Unable to locate gmp.h

Solution: Create a symbolic link.

ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h

3. Compile

This will take some time. If make has finished without errors we’ll use checkinstall to create a Debian/Ubuntu package file that will contain all the new files we just created. That way we’ll also be able to remove the files again easily using a package manager of our choice.

make
checkinstall

checkinstall will ask for a package name, a maintaner and a description. As package name I would suggest using php7 to avoid conflicts with existing PHP installations. After that a .deb file will be created and also installed on our system.

The remove the changes again we can simply use:

apt-get remove php7

Known issues during make

Error: Note telling you to use –no-check-certificate because of pear.php.net certificate missmatch.

Solution: It seems the pear.php.net resolved to fault IP. Just use the following configure option to disable pear for the time beeing.

..
--with-mysqli=/usr/bin/mysql_config \
--enable-fpm \
--without-pear

Pear may be installed manually later.

4. First tests

The most simple test would be using the command line interface (CLI)

/opt/php7/bin/php -v

This should return version information like version numebr PHP 7.0.0beta1.  The next command will return data regarding the installed modules as well as configuration paramenters.

/opt/php7/bin/php -v

5. Using the php-fpm module with Apache and fastcgi

We’ll assume that the Apache webserver is installed an running. First we’ll install the fastcgi module and enable the action module.

apt-get install apache2-mpm-worker libapache2-mod-fastcgi
a2enmod action

Next step is to create config files for php-fpm and start the process.

cd /opt/php7/etc
sudo cp php-fpm.conf.default php-fpm.conf
sudo cat php-fpm.d/www.conf.default | sed s/nobody/www-data/ > php-fpm.d/www.conf
sudo ../sbin/php-fpm

With that we have created a www.conf file defining a process pool. We replaced the user and group values nobody with www-data and launched the php-fpm process. If the system already has a php-fpm module installed, for example PHP5, we should also change the port number in that file.

The only thing left is now to add the following line into a VirtualHost configuration of our choice.

...
# This will override the default php5 handler from php5.conf
<FilesMatch ".+\.ph(p[345]?|t|tml)$">
 SetHandler php7-fcgi


# Add Action to route requests to php-fpm
Action php7-fcgi /php7-fcgi
# php7.fcgi doesn't have to exit but the folder does and needs to be within
# document root
Alias /php7-fcgi /var/www/php7.fcgi
FastCGIExternalServer /var/www/php7.fcgi -host 127.0.0.1:9000
...

Instead of  /var/www you have the use the real path to our DocumentRoot folder. Apache needs to be restarted for the changes to take effect.

Example Initscript for our new php-fpm server process

#! /bin/sh
### BEGIN INIT INFO
# Provides:          php-7.0.0beta1-1-fpm
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts php-7.0.0beta1-1-fpm
# Description:       This starts the PHP FastCGI Process Manager daemon
### END INIT INFO
php_fpm_BIN=/opt/php7/sbin/php-fpm
php_fpm_CONF=/opt/php7/etc/php-fpm.conf
php_fpm_PID=/opt/php7/var/run/php-fpm.pid
php_opts="--fpm-config $php_fpm_CONF --pid $php_fpm_PID"
wait_for_pid () {
        try=0
        while test $try -lt 35 ; do
                case "$1" in
                        'created')
                        if [ -f "$2" ] ; then
                                try=''
                                break
                        fi
                        ;;
                        'removed')
                        if [ ! -f "$2" ] ; then
                                try=''
                                break
                        fi
                        ;;
                esac
                echo -n .
                try=`expr $try + 1`
                sleep 1
        done
}
case "$1" in
        start)
                echo -n "Starting php-fpm "
                $php_fpm_BIN $php_opts
                if [ "$?" != 0 ] ; then
                        echo " failed"
                        exit 1
                fi
                wait_for_pid created $php_fpm_PID
                if [ -n "$try" ] ; then
                        echo " failed"
                        exit 1
                else
                        echo " done"
                fi
        ;;
        stop)
                echo -n "Gracefully shutting down php-fpm "
                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi
                kill -QUIT `cat $php_fpm_PID`
                wait_for_pid removed $php_fpm_PID
                if [ -n "$try" ] ; then
                        echo " failed. Use force-exit"
                        exit 1
                else
                        echo " done"
                       echo " done"
                fi
        ;;
        force-quit)
                echo -n "Terminating php-fpm "
                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi
                kill -TERM `cat $php_fpm_PID`
                wait_for_pid removed $php_fpm_PID
                if [ -n "$try" ] ; then
                        echo " failed"
                        exit 1
                else
                        echo " done"
                fi
        ;;
        restart)
                $0 stop
                $0 start
        ;;
        reload)
                echo -n "Reload service php-fpm 
                if [ ! -r $php_fpm_PID ] ; then
                        echo "warning, no pid file found - php-fpm is not running ?"
                        exit 1
                fi
                kill -USR2 `cat $php_fpm_PID`
                echo " done"
        ;;
        *)
                echo "Usage: $0 {start|stop|force-quit|restart|reload}"
                exit 1
        ;;
esac

You might have to create the following folders manually /opt/php7/var /opt/php7/var/log and /opt/php7/var/run.

6. Use php-fpm with NginX

If your NginX server is already setup to work with a php-fpm process the following lines should be found in the configuration files:

location ~ \.php$
   {
       include /etc/nginx/fastcgi_params;
       fastcgi_pass 127.0.0.1:9000;
       fastcgi_index index.php;
       fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
   }

In that case you should already have changed the TCP/IP port in the www.pool config file.  Just enter the new port instead of 9000 in the NginX configuration. After a reload the VirtualHost should then user PHP7 instead of PHP5.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.