Ubuntu 12.04, Multiple PHP Versions, and Virtualmin using PHPBrew

So, I wanted to upgrade to PHP 5.4 from 5.3 but I didn't want to do it server wide since I host multiple websites. Therefore, I wanted to do it site by site so that I can test to ensure all is working well. Unforuntately, Ubuntu doesn't have the cool feature CentOS does where I can install multiple versions of a software without having to compile it myself (at least I couldn't find anything). So, I'm forced to compile things myself.

After researching, I decided on phpbrew to handle this job for me.

I should start by saying that I personally have used the repository from dotdeb.org to upgrade to the latest (almost) PHP 5.3 versions (yes I know it is fore Debian Squeeze but its works for Ubuntu 12.04). I'm not really going to go over that in this article so you can do your own research if you want/need to.

First, I installed PHPBrew using the instructions per their Github page:

curl -O https://raw.github.com/c9s/phpbrew/master/phpbrew
 chmod +x phpbrew
 sudo cp phpbrew /usr/bin/phpbrew

By default, PHPBrew installs the PHP versions into your home directory; but I wanted to use the installed PHP versions system wide, so I followed their instructions for installing phpbrew into system-wide environment:

First, sudo as a root user or login as a root user:

sudo -i

Now initialize your phpbrew bashrc for root:

phpbrew init

Now export phpbrew paths to your desired paths, edit your ~/.phpbrew/init

export PHPBREW_ROOT=/opt/phpbrew

Source your phpbrew bashrc

source ~/.phpbrew/bashrc

Now I compiled PHP 5.4.14 with Ubuntu's defaults:

sudo apt-get install libmcrypt-dev
 phpbrew install php-5.4.13 +default +mysql +gettext +mcrypt +intl +iconv +ftp +exif +dba +openssl +soap +apxs2=/usr/bin/apxs2 -- --with-libdir=lib/x86_64-linux-gnu --with-gd=shared --enable-gd-native-ttf --with-jpeg-dir=/usr --with-png-dir=/usr --enable-wddx --with-mysql-sock=/var/run/mysqld/mysqld.sock

But I like to add a few extras

sudo apt-get install libmcrypt-dev libfreetype6
 phpbrew install php-5.4.13 +default +mysql +gettext +mcrypt +intl +iconv +ftp +exif +dba +openssl +soap +ipv6 +imap +debug +cgi +exif +apxs2=/usr/bin/apxs2 -- --with-libdir=lib/x86_64-linux-gnu --with-gd=shared --enable-gd-native-ttf --with-jpeg-dir=/usr --with-png-dir=/usr --enable-wddx --with-mysql-sock=/var/run/mysqld/mysqld.sock --with-freetype-dir=/usr/include/freetype2/freetype

Site back and relax or go do something else as it will take a good while for everything to compile.

Here's a note from PHPBrew's GitHub page:

Now your php(s) will be installed under the /opt/phpbrew path, To let your users can use php(s) built by phpbrew, you need to exportPHPBREW_ROOT environment in /etc/bashrc or in /etc/profile.d/phpbrew for bash users, before they load the phpbrew/bashrc file.

export PHPBREW_ROOT=/opt/phpbrew
 source /opt/phpbrew/bashrc

After PHP is compiled, let's tell Virtualmin that it's available to use.

Virtualmin looks for additional PHPs in a specific place so we have to do some symlinking to ensure it finds our PHPBrew installed PHP.

sudo mkdir /opt/rh/
 sudo ln -s /opt/phpbrew/php/php-5.4.14 /opt/rh/php54

Optionally, you could've also installed PHP directly into that directory during the phpbrew install command above but you'll need to read PHPBrews docs for that as I prefer this method as I can always symlink anything to anywhere).

Okay, now before we flip the switch, we have to do a little more manipulation. When you tell Virtualmin to use a different version of PHP, it will symnlink $ HOME/etc/php.ini to $ HOME/etc/php5.4/php.ini. For existing domains at least, this does not exist. So you'll either need to create the php5.4 directory and copy etc/php5/php.ini into it or symlink to it. Personally, I symlink so that I only have to make a change in one place as I'm not planning to bounce back and forth between the two versions for individual domains and thus there is not a need to maintain two php.ini files:

mkdir /home/myuser/etc/php5.4
 ln -s /home/myuser/etc/php5/php.ini /home/myuser/etc/php5.4/php.ini

Note that if you are doing this with root, you may need to update the permissions if applicable.

Now if you want a little script to loop through all servers and subservers and do this for you, then you can copy this little script to a file and then run it:

 for dir in /home/*/
         dir=$  {dir%*/}
         dir=$  {dir##*/}
         mkdir /home/$  dir/etc/php5.4
         ln -s /home/$  dir/etc/php5/php.ini /home/$  dir/etc/php5.4/php.ini
         for dir2 in /home/$  dir/domains/*/
                 dir2=$  {dir2%*/}
                 dir2=$  {dir2##*/}
                 mkdir /home/$  dir/domains/$  dir2/etc/php5.4
                 ln -s /home/$  dir/domains/$  dir2/etc/php5/php.ini /home/$  dir/domains/$  dir2/etc/php5.4/php.ini

If your code is not optimized for PHP 5.4, you'll want to do one of two things or even both. You can turn off strict notices in php.ini by changing error_reporting to error_reporting = E_ALL & ~E_STRICT & ~E_NOTICE & ~E_DEPRECATED. Or you can make sure that display_errors = off; this should be done anyway for production sites.

Now, let's make the switch. Go into Virtualmin and select the desired domain. Then go to Server Configuration -> PHP Versions and select 5.4.14 for the Default HTML directory then click Save Versions. That server will now be using PHP 5.4.14.

You can set the PHP version default for new servers by going to System Settings -> Server Templates -> Apache Website. Note that it defaults to Highest Available and thus will use 5.4 unless otherwise noted.

Now, I use eAccelerator so I had to compile it for PHP 5.4.

 cd /usr/local/src
 wget https://github.com/eaccelerator/eaccelerator/archive/master.zip
 unzip master.zip
 cd eaccelerator-master
 export PHP_PREFIX=/opt/phpbrew/php/php-5.4.14
 $  PHP_PREFIX/bin/phpize
 ./configure --enable-shared --with-php-config=$  PHP_PREFIX/bin/php-config
 make install

Then setup eaccelerator per their instructions.

My personal notes 🙂

 phpbrew ext install gd
 phpbrew ext install imap -- --with-kerberos --with-imap-ssl
 phpbrew ext install openssl
 phpbrew ext install pspell
 phpbrew ext install xdebug
 phpbrew ext install imagick 3.1.0RC2

Leave a Reply