Running multiple PHP versions and compiling from source

We had a peculiar situation where both PHP5 and PHP7 were needed at the same time on a FreeBSD server. It was also prohibitive to get root or sudo access on the managing account. The solution was to compile PHP from source with fpm, run fpm on a UNIX socket and wire the specific domain which needed PHP7 through Nginx.

Compiling from source

Compiling PHP is pretty straightforward but you can easily forget crucial configure flags. First get the source archive. After trial and error, this appears to be “good enough” for Laravel 5.6 requirements.

./configure -prefix=/home/foo/php7 --with-openssl --enable-mbstring --with-pdo-mysql --enable-fpm --with-config-file-path=/home/foo/php7 --with-config-file-scan-dir=/home/foo/php7 --with-iconv --with-gmp --with-gd

Followed by
make && make install
copy php.ini-development file from source to the –with-config-file-path directory and call it php.ini. In PREFIX/bin confirm that php binary is loading your ini file by running
./php --ini
If you made a mistake in your configure run, you have to make clean first or the changed options won’t be picked up.

Configuring fpm

In your PREFIX/etc folder, check php-fpm.conf. The only lines I bothered to verify and edit were pid, error_log and include, the rest can be left as is.

Inside folder php-fpm.d create a config file like my.subdomain.conf and add something like

listen = /location/of/php-fpm.sock
user = foo
group = foo
pm = dynamic
pm.max_children = 5
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 1
pm.max_requests = 200
listen.backlog = -1
pm.status_path = /status
request_terminate_timeout = 30s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

You can study fpm config in great details but this is enough to get you going.

Now you can run your PHP7 fpm process in PREFIX/sbin with
./php-fpm --fpm-config /prefix/etc/php-fpm.conf
Since we don’t have any init scripts in this case, we must be able to kill it also. Find it with
ps aux | grep fpm
and kill with
kill -QUIT pid
Make sure it says php-fpm: master process in the ps output, killing children doesn’t do anything, just respawns them.

Now you just need to wire up your Nginx to use this fpm instead of the PHP5 system one by specifying
fastcgi_pass unix:/location/of/php-fpm.sock;
We now have PHP dualstack with some web apps running on system provided PHP5 and some on our own built PHP7. We did not need root for this process, except possibly for configuring Nginx.

One obvious downside is that you now have to take care of updating your PHP version on your own but that is one view we had to sacrifice. Updates should be relatively easy and fast since make install won’t remove your config files in existing installation and compiling PHP takes just a few minutes.


2565 Total Views 1 Views Today