Ставим древнюю версию php 5.2 на Ubuntu 14.04 (nginx/apache+php_fastcgi)

// Март 28th, 2016 // CMS, PHP, Ubuntu, Системное администрирование

zombie-iconВ этом посте я расскажу, как на современный веб-сервер можно поставить такую древнюю версию php, как 5.2.17 Зачем это может понадобиться — даже не спрашивайте :) В качестве примера можно представить ситуацию, когда необходимо развернуть какой-нибудь стародавний скрипт и отдебажить его или посмотреть вживую. В общем всех некрофилов — велкам под кат.

old_computer

Тестовый стенд

Операционка — Ubuntu 14.04 LTS За основу возьмем мой конфиг из статьи Настройка nginx для хостинга. Там как раз реализована схема «nginx+php_fpm». Итак на машине уже стоит nginx, mysql, php_fpm.

Часть 1: Nginx+Apache+php_fpm+php_fcgi

Сначала мы попробуем организовать следующую схему работы.
Nginx (port 80) работает в качестве reverse-proxy и принимает все запросы. Если запрос идёт с определенным hostname (vhost nginx -> server_name) — он отправляет его на Apache (к которому подключен старый ламповый php5.2), если на все остальные сайты (другой vhost nginx) — то запрос идёт на новый php_fpm.

Установка второго php в систему (php 5.2.17)

Наша задача в этой части — скачать, установить и настроить древний php 5.2.17 так, чтобы он мирно сосуществовал с текущим и не мешал ему. Поехали.
Первым делом доставим необходимые для сборки пакеты:

sudo apt-get install libxml2-dev libmysqlclient-dev libcurl4-gnutls-dev libpng12-dev libjpeg62-dev make libxslt1-dev libbz2-dev libmcrypt-dev libmhash-dev libfcgi-dev libmhash-dev checkinstall

Теперь нам надо сделать символические ссылки на библиотечки, т.к. скрипт конфигурации php будет искать их именно в этих местах.
Я делел симлинки на простые so-шники (без версий).

Для 64-bit систем

ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so.62.0.0 /usr/lib/libjpeg.so 
ln -s /lib/x86_64-linux-gnu/libpng12.so.0.50.0 /usr/lib/libpng.so 
ln -s /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18.0.0 /usr/lib/libmysqlclient.so

Для 32-bit систем  Мне вас очень жаль (:

ln -s /usr/lib/i386-linux-gnu/libjpeg.a /usr/lib/libjpeg.a
ln -s /lib/i386-linux-gnu/libpng12.so.0.49.0 /usr/lib/libpng.so
ln -s /usr/lib/i386-linux-gnu/libmysqlclient.so.18.0.0 /usr/lib/libmysqlclient.so

Теперь качаем исходники нужной нам версии php из Музея PHP.

mkdir /opt/sources
cd /opt/sources
wget http://museum.php.net/php5/php-5.2.17.tar.gz
tar zxf ./php-5.2.17.tar.gz
cd ./php-5.2.17

Определимся с путями. Наш новый старый php будет лежать вот тут: /opt/php5.2 так что запускаем скрипт конфигурации:

./configure --prefix=/opt/php5.2 --with-config-file-path=/opt/php5.2 --with-mysqli --with-mysql --with-curl --with-gd --with-jpeg-dir --enable-cli --enable-fastcgi --enable-discard-path --enable-force-cgi-redirect --enable-mbstring --with-mcrypt

Если он будет материться — доставляйте необходимые библиотеки. Если всё ок — идем дальше. Перед тем, как приступить к компиляции нам надо наложить патч (иначе не скомпилится). Патчим и собираем.

wget https://mail.gnome.org/archives/xml/2012-August/txtbgxGXAvz4N.txt
patch -p0 -b < txtbgxGXAvz4N.txt
make

Чтобы не замусоривать систему соберем deb-пакет из исходников с помощью checkinstall.

checkinstall

Параметры для пакета я выставил вот такие:

This package will be built according to these values:
0 - Maintainer: [ root@host ]
1 - Summary: [ PHP 5.2.17 ]
2 - Name: [ php5.2.17 ]
3 - Version: [ 5.2.17 ]
4 - Release: [ 1 ]
5 - License: [ GPL ]
6 - Group: [ checkinstall ]
7 - Architecture: [ amd64 ]
8 - Source location: [ php-5.2.17 ]
9 - Alternate source location: [ ]
10 - Requires: [ ]
11 - Provides: [ php ]
12 - Conflicts: [ ]
13 - Replaces: [ ]
Enter a number to change any of them or press ENTER to continue: 

Теперь запускаем процесс установки.

Installing with make install... 
========================= Installation results ===========================
Installing PHP SAPI module: cgi
Installing PHP CGI binary: /opt/php5.2/bin/
Installing PHP CLI binary: /opt/php5.2/bin/
Installing PHP CLI man page: /opt/php5.2/man/man1/
Installing build environment: /opt/php5.2/lib/php/build/
Installing header files: /opt/php5.2/include/php/
Installing helper programs: /opt/php5.2/bin/ program: phpize program: php-config
Installing man pages: /opt/php5.2/man/man1/ page: phpize.1 page: php-config.1
Installing PEAR environment: /opt/php5.2/lib/php/ [PEAR] Archive_Tar - installed: 1.3.7 [PEAR] Console_Getopt - installed: 1.2.3 [PEAR] Structures_Graph- installed: 1.0.3 [PEAR] XML_Util - installed: 1.2.1 [PEAR] PEAR - installed: 1.9.1 Wrote PEAR system config file at: /opt/php5.2/etc/pear.conf You may want to add: /opt/php5.2/lib/php to your php.ini include_path Installing PDO headers: /opt/php5.2/include/php/ext/pdo/

Отлично, теперь сразу видно что куда поставилось.

Проверяем версию консольного php

root@host:/sources/php-5.2.17# /opt/php5.2/bin/php -v
PHP 5.2.17 (cli) (built: Mar 9 2016 08:11:36)

Выставляем права на директорию:

chmod ugo+rX -R /opt/php5.2/

Дальше, если вам не нужен Apache и вы хотете подключить эту версию php напрямую к nginx — переходите ко второй части статьи.

Устаналививаем Apache

Веб-сервер ставим из пакетов нашего дистрибьютива.

apt-get install apache2

Т.к. 80 порт занят nginx-ом — вываливаются сообщения об ошибках:

AH00557: apache2: apr_sockaddr_info_get() failed for site2
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
(98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
(98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80

Надо перенести Apache на порт 8080.
В /etc/apache2/ports.conf изменяем номер порта в Listen 80 на 8080 и пробуем запустить веб-сервер.

service apache2 restart

Доставляем модуль fcgi.

sudo apt-get install libapache2-mod-fastcgi

Создаем файлик-обертку для php /var/www/cgi-bin/php52.fcgi вот такого вида:

#!/bin/sh
export PHP_FCGI_CHILDREN=4
export PHP_FCGI_MAX_REQUESTS=200
#export PHPRC="/var/www/php.ini" //Путь к конфигу
exec /opt/php5.2/bin/php-cgi

Далее в файле /etc/apache2/sites-enabled/000-default.conf (описание vhost-а по-умолчанию) пишем вверху новый порт:

...
# php_admin_flag engine off (т.к. у меня не было mod_php строку закомментировал)
ScriptAlias /cgi-bin "/var/www/cgi-bin"
Action application/x-httpd-php /cgi-bin/php52.fcgi

Кладем phpinfo.php в /var/www/html, потом заходим по ip на сайт и смотрим результат:
http://192.168.0.xx:8080/phpinfo.php

Настойка Vhost в Apache

Тепеь создаём файлик /etc/apache2/sites-avaliable/sitename.conf со следующим содержанием:

ServerName site.org
ServerAlias www.site.org

ServerAdmin webmaster@localhost
DocumentRoot /home/www-data/site.org/html

#LogLevel info ssl:warn

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

# for php 5.2.17
# php_admin_flag engine off
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
AddType application/x-httpd-php .php
Action application/x-httpd-php /cgi-bin/php52.fcgi



Require all granted

Делаем симлинк из sites-avaliable на него.
Теперь у нас работает Apache+php5.2. Дальше будем подключать к этой конструкции nginx.

Настройка Vhost в nginx

Создаем файлик sitename в /etc/nginx/sites-avaliable вот такого вида

# old site
server {
listen 80;
server_name site.org;
index index.htm index.html index.php;

location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

}

Значит при попадании запроса с этим site.org nginx будет проксировать его на apache. Делаем симлинк в sites-enable, перезагружам nginx и смотрим, ушел ли запрос на apache.

Часть 2: Nginx + php_fpm + php_fcgi

После того, как всё завелось я задался резонным вопросом — а зачем собственно нужен Apache. Может выкинуть его нафиг? Приступим!
Ставим пакет для службы.

sudo apt-get install spawn-fcgi

Nginx будет смотреть заголовок host (server_name) и проксировать запрос либо на php5.2 в режиме fcgi — port 9020, либо на новый php_fpm (основной) — port 9010.
Для этого сделаем вторую обертку для nginx.

Создаём каталог для pid-файла:

mkdir /var/run/php52-fastcgi

Делаем саму обертку.
/var/www/cgi-bin/php52tcp.fcgi

#!/bin/bash

FASTCGI_USER=www-data
FASTCGI_GROUP=www-data
ADDRESS=127.0.0.1
PORT=9020
PIDFILE=/var/run/php52-fastcgi/php-fastcgi.pid
CHILDREN=6
PHP5=/opt/php5.2/bin/php-cgi

/usr/bin/spawn-fcgi -a $ADDRESS -p $PORT -P $PIDFILE -C $CHILDREN -u $FASTCGI_USER -g $FASTCGI_GROUP -f $PHP5

Теперь делаем файл службы.

/etc/init.d/php52-fastcgi

Скачать можно тут. А то на страничке пробелы похерятся.

#!/bin/bash
PHP_SCRIPT=/var/www/cgi-bin/php52tcp.fcgi
FASTCGI_USER=www-data
FASTCGI_GROUP=www-data
PID_DIR=/var/run/php52-fastcgi
PID_FILE=/var/run/php52-fastcgi/php-fastcgi.pid
RET_VAL=0
case "$1" in
start)
if [[ ! -d $PID_DIR ]]
then
mkdir $PID_DIR
chown $FASTCGI_USER:$FASTCGI_GROUP $PID_DIR
chmod 0770 $PID_DIR
fi
if [[ -r $PID_FILE ]]
then
echo "php-fastcgi already running with PID `cat $PID_FILE`"
RET_VAL=1
else
$PHP_SCRIPT
RET_VAL=$?
fi
;;
stop)
if [[ -r $PID_FILE ]]
then
kill `cat $PID_FILE`
rm $PID_FILE
RET_VAL=$?
else
echo "Could not find PID file $PID_FILE"
RET_VAL=1
fi
;;
restart)
if [[ -r $PID_FILE ]]
then
kill `cat $PID_FILE`
rm $PID_FILE
RET_VAL=$?
else
echo "Could not find PID file $PID_FILE"
fi
$PHP_SCRIPT
RET_VAL=$?
;;
status)
if [[ -r $PID_FILE ]]
then
echo "php-fastcgi running with PID `cat $PID_FILE`"
RET_VAL=$?
else
echo "Could not find PID file $PID_FILE, php-fastcgi does not appear to be running"
fi
;;
*)
echo "Usage: php-fastcgi {start|stop|restart|status}"
RET_VAL=1
;;
esac
exit $RET_VAL

Ставим бит исполнения и проверяем нашу новую службу.

chmod +x /etc/init.d/php52-fastcgi
chmod 0755 /var/www/cgi-bin/php52.fcgi
/etc/init.d/php52-fastcgi start
ps aux | grep php

Должны работать сразу и php-fpm и древний php52 через fcgi.

/etc/init.d/php52-fastcgi stop
ps aux | grep php

Смотрим процессы — новая служба должна убиться. Этим мы проверим корректность работы с pid-файлом.
Отлично, теперь можно добавить её в систему.

update-rc.d php52-fastcgi defaults

Теперь осталось добавить vhost для nginx с новой службой.

# PHP-FPM (backend)
upstream php52 {
server 127.0.0.1:9020;
}

 
# Конфиг Nginx (frontend)
server {
 

# Защита от бага http://forum.nginx.org/read.php?2,154025,154036
# server_name_in_redirect off;
 
# Защита от бага upstream-sent-too-big-header
fastcgi_buffers 8 32k;
fastcgi_buffer_size 32k;
 
# Порт, принимаемые HOST и путь к сайту
listen 80;
server_name site.org;
 
set $www_folder '/home/www-data';
set $root_path '$www_folder/$host/html';
 
# for turbo realpath extension http://php.webtutor.pl/en/2011/07/01/running-php-on-nfs-new-version-of-turbo_realpath-extension/
fastcgi_param realpath_cache_basedir '/tmp:/usr/share/php:/usr/share/phpmyadmin:$root_path';
# root $root_path;
index index.htm index.html index.php;
 
# Запросы на картинки, стили и другую статику
location ~* \.(css|js|swf|ico|png|jpg)$ {
root $root_path;
access_log off;
expires  30d;
}

 
# Защита от брутфорса
location ~ ^/(wp-login\.php) {
auth_basic "Admin zone";
auth_basic_user_file /home/www-data/.htpasswd;
 
index index.htm index.html index.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_param SCRIPT_FILENAME $root_path/$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_path; # этот параметр нужен несмотря на root в секции server
# fastcgi_param REMOTE_ADDR $http_x_real_ip;
fastcgi_pass php52;
}

 
# Запросы непосредственно .php-файлов, например утилит или index.php (не кэшируются)
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_param SCRIPT_FILENAME $root_path/$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_path; # этот параметр нужен несмотря на root в секции server
# fastcgi_param REMOTE_ADDR $http_x_real_ip;
fastcgi_pass php52;
fastcgi_read_timeout 900; # 15 minutes
}

# Копия предыдущего для internal переадресации
location @phpscripts {
include /etc/nginx/fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_param SCRIPT_FILENAME $root_path/$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_path; # этот параметр нужен несмотря на root в секции server
# fastcgi_param REMOTE_ADDR $http_x_real_ip;
fastcgi_pass php52;
fastcgi_read_timeout 900; # 15 minutes
}

 

# Остальные запросы также идут на PHP-FPM, если $uri не существует (через memcache)

location / {
default_type text/html; #add_header    Content-Type  "text/html";
root  $root_path;
 
if (!-e $request_filename) {
return 404;
}
error_page      404 502 504 403 405 = @php;
}

 

# Для отладки
location /status {
include /etc/nginx/fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_param SCRIPT_FILENAME $root_path/index.php;
fastcgi_pass php52;
}

 

location /ping {
include /etc/nginx/fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_param SCRIPT_FILENAME $root_path/index.php;
fastcgi_pass php52;
}

 
# Веб-приложение
location @php {
include /etc/nginx/fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_param SCRIPT_FILENAME $root_path/index.php;
# fastcgi_param REMOTE_ADDR $http_x_real_ip;
fastcgi_pass php52;
fastcgi_read_timeout 900; # 15 minutes
}
 
# Переопеределение 502 ошибки
error_page     502 = /502.htm;
location = /502.htm {
root  $www_folder;
}
 
 
# Защита от просмотра .htaccess и .htpasswd файлов
location ~ /\.ht {
deny  all;
}
 
# Защита от просмотра svn-файлов
location ~ /.svn/ {
deny all;
}

 
# Статус запросы (/status) и пинг(/ping) запросы от системы мониторинга
location ~ ^/(status|ping)$ {
include fastcgi_params;
fastcgi_param SERVER_NAME $http_host; # For correct $_SERVER['HTTP_HOST'] after fastcgi_params
fastcgi_pass 127.0.0.1:9010;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
allow 127.0.0.1;
deny all;
}

 
# awstats
location ^~ /awstats-icon {
alias /usr/share/awstats/icon/;
access_log off;
}

 
location ^~ /awstatscss {
alias /usr/share/doc/awstats/examples/css/;
access_log off;
}
 
location ^~ /awstatsclasses {
alias /usr/share/doc/awstats/examples/classes/;
access_log off;
}
 
location ~ ^/cgi-bin {
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /usr/lib$fastcgi_script_name;
}
}

 

Донастройка Joomla

Т.к. mysql у меня вообще говоря в utf-8, а старый движок в cp1251 нужно принудительно в нем (joomla) настроить кодировку соединения с БД. Для этого в Index.php после события onStart добавляем выполнение запроса SET NAMES.

index.php

// trigger the onStart events
$_MAMBOTS->trigger( 'onStart' );

if (file_exists( $mosConfig_absolute_path .'/components/com_sef/sef.php' )) {
require_once( $mosConfig_absolute_path .'/components/com_sef/sef.php' );
} else {
require_once( $mosConfig_absolute_path .'/includes/sef.php' );
}
require_once( $mosConfig_absolute_path .'/includes/frontend.php' );

// to php5.2
$database->setQuery("SET NAMES 'cp1251'");
$database->query();

 

Потом повторяем процедуру для файла /administrator/index2.php

require_once( '../globals.php' );
require_once( '../configuration.php' );
require_once( $mosConfig_absolute_path . '/includes/joomla.php' );
include_once( $mosConfig_absolute_path . '/language/'. $mosConfig_lang .'.php' );
require_once( $mosConfig_absolute_path . '/administrator/includes/admin.php' );

// for php5.2
$database->setQuery("SET NAMES 'cp1251'");
$database->query();

Перезагружаем страницу, смотрим — вопросики исчезли.

Ссылки

http://iantonov.me/page/ustanovka-php-52-v-debian-78-sobiraem-staryj-php-iz-ishodnikov https://habrahabr.ru/sandbox/56953/ https://www.litespeedtech.com/support/forum/threads/solved-compile-php-5-2.6887/ PHP Музей (старые версии) Зеркало патча из статьи: http://tokarchuk.ru/wp-content/uploads/2016/03/php-5.2.17-patch.txt
https://habrahabr.ru/sandbox/56953/
https://www.linode.com/docs/websites/nginx/install-nginx-and-php-via-fastcgi-on-ubuntu-12-04-precise-pangolin/

http://www.x83.net/nginx-php-5-2-17-php-fpm/

http://blog.soros.org.ua/2014/10/recompile-php-5-3-x-client-libs-mariadb/

https://github.com/phpbrew/phpbrew/issues/492

 

Share

Спасибо!


Если вам помогла статья, или вы хотите поддержать мои исследования и блог - вот лучший способ сделать это:


6 Responses to “Ставим древнюю версию php 5.2 на Ubuntu 14.04 (nginx/apache+php_fastcgi)”

  1. osterik:

    ошбочка, пропущен пробел
    «ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so.62.0.0/usr/lib/libjpeg.so»
    «ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so.62.0.0 /usr/lib/libjpeg.so»

  2. osterik:

    еще одна
    «patch -p0 -b < txtbgxGXAvz4N.txt»
    «patch -p0 -b < txtbgxGXAvz4N.txt"
    тут может парсер вмешался :)

  3. oster:

    еще опечатка.
    вместо
    «Создаем файлик-обертку для php /var/www/cgi-bin/php52.cgi вот такого вида:»
    надо
    «Создаем файлик-обертку для php /var/www/cgi-bin/php52.fcgi вот такого вида:»

  4. Alex:

    Зачем ставить древнюю пыху?

    • google.com Андрей Токарчук:

      Когда тебе достался адово древний проект, который ни под чем другим ну просто не запускается, а ты палатся это сделать раз 10, твои глаза кровоточат то впомнишь этот пост))

Комментировать