Ставим древнюю версию php 5.2 на Ubuntu 14.04 (nginx/apache+php_fastcgi)
В этом посте я расскажу, как на современный веб-сервер можно поставить такую древнюю версию php, как 5.2.17 Зачем это может понадобиться – даже не спрашивайте 🙂 В качестве примера можно представить ситуацию, когда необходимо развернуть какой-нибудь стародавний скрипт и отдебажить его или посмотреть вживую. В общем всех некрофилов – велкам под кат.
Тестовый стенд
Операционка – 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 так, чтобы он мирно сосуществовал с текущим и не мешал ему. Поехали.
Первым делом доставим необходимые для сборки пакеты:
1 | 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 систем
1 2 3 | 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 систем Мне вас очень жаль (:
1 2 3 | 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.
1 2 3 4 5 | 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 так что запускаем скрипт конфигурации:
1 | ./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 |
Если он будет материться – доставляйте необходимые библиотеки. Если всё ок – идем дальше. Перед тем, как приступить к компиляции нам надо наложить патч (иначе не скомпилится). Патчим и собираем.
1 2 3 | wget https://mail.gnome.org/archives/xml/2012-August/txtbgxGXAvz4N.txt patch -p0 -b < txtbgxGXAvz4N.txt make |
Чтобы не замусоривать систему соберем deb-пакет из исходников с помощью checkinstall.
1 | checkinstall |
Параметры для пакета я выставил вот такие:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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: |
Теперь запускаем процесс установки.
1 2 3 4 5 6 7 8 9 10 11 | 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
1 2 | 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) |
Выставляем права на директорию:
1 | chmod ugo+rX -R /opt/php5.2/ |
Дальше, если вам не нужен Apache и вы хотете подключить эту версию php напрямую к nginx – переходите ко второй части статьи.
Устаналививаем Apache
Веб-сервер ставим из пакетов нашего дистрибьютива.
1 | apt-get install apache2 |
Т.к. 80 порт занят nginx-ом – вываливаются сообщения об ошибках:
1 2 3 4 | 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 и пробуем запустить веб-сервер.
1 | service apache2 restart |
Доставляем модуль fcgi.
1 | sudo apt-get install libapache2-mod-fastcgi |
Создаем файлик-обертку для php /var/www/cgi-bin/php52.fcgi вот такого вида:
1 2 3 4 5 | #!/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-а по-умолчанию) пишем вверху новый порт:
1 2 3 4 | ... # 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 со следующим содержанием:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 вот такого вида
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # 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. Может выкинуть его нафиг? Приступим!
Ставим пакет для службы.
1 | sudo apt-get install spawn-fcgi |
Nginx будет смотреть заголовок host (server_name) и проксировать запрос либо на php5.2 в режиме fcgi – port 9020, либо на новый php_fpm (основной) – port 9010.
Для этого сделаем вторую обертку для nginx.
Создаём каталог для pid-файла:
1 | mkdir /var/run/php52-fastcgi |
Делаем саму обертку.
/var/www/cgi-bin/php52tcp.fcgi
1 2 3 4 5 6 7 8 9 10 11 | #!/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
Скачать можно тут. А то на страничке пробелы похерятся.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #!/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 |
Ставим бит исполнения и проверяем нашу новую службу.
1 2 3 4 | 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.
1 2 | /etc/init.d/php52-fastcgi stop ps aux | grep php |
Смотрим процессы – новая служба должна убиться. Этим мы проверим корректность работы с pid-файлом.
Отлично, теперь можно добавить её в систему.
1 | update-rc.d php52-fastcgi defaults |
Теперь осталось добавить vhost для nginx с новой службой.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | # PHP-FPM (backend) upstream php52 { server 127.0.0.1:9020; } # Конфиг Nginx (frontend) server { # Защита от бага <a href="http://forum.nginx.org/read.php?2,154025,154036">http://forum.nginx.org/read.php?2,154025,154036</a> # 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 <a href="http://php.webtutor.pl/en/2011/07/01/running-php-on-nfs-new-version-of-turbo_realpath-extension/">http://php.webtutor.pl/en/2011/07/01/running-php-on-nfs-new-version-of-turbo_realpath-extension/</a> 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
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 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
1 2 3 4 5 6 7 8 9 | 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 Музей (старые версии) Зеркало патча из статьи: https://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
ошбочка, пропущен пробел
“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”
Поправил
еще одна
“patch -p0 -b < txtbgxGXAvz4N.txt”
“patch -p0 -b < txtbgxGXAvz4N.txt"
тут может парсер вмешался 🙂
Да, нажимаете на иконку справа от кода – открывается чистый валидный.
Сейчас всё исправлено, что в комментах. Если насли что-то еще – пишите, тут парсер может код портить.
еще опечатка.
вместо
“Создаем файлик-обертку для php /var/www/cgi-bin/php52.cgi вот такого вида:”
надо
“Создаем файлик-обертку для php /var/www/cgi-bin/php52.fcgi вот такого вида:”
Спасибо, действительно были опечатки!!
Шел 2018 год. А ошибки в статье до сих пор присутствуют не смотря на то, что в комментариях они описаны и автором прочитаны =)
В /etc/apache2/sites-enabled/000-default.conf
ты забыл про
AddType application/x-httpd-php .php
без ниго ничерта не работает! а я столько времени убил.
+ надо врубить модуль апача который за связку с пхп отвечает, забыл уже как называется, типа pache2-php-fcgi
Зачем ставить древнюю пыху?
Когда тебе достался адово древний проект, который ни под чем другим ну просто не запускается, а ты палатся это сделать раз 10, твои глаза кровоточат то впомнишь этот пост))
Всем доброго дня. Или как у меня сайты зашифрованы исходников нет. Базы данных по 4 гига… + сдохло железо и нет ни одного дампа… спасибо за статью. Буду пытаться установить
Удачи тезка!
ААА!!! СЛООЖНА!! 😀
По-моему уже проще завести Docker… Ну или VirtualBox на крайняк…
eswww@expertnegotiator:/etc/apache2/sites-available$ sudo service apache2 restart
* Restarting web server apache2 [fail]
* The apache2 configtest failed.
Output of config test was:
AH00526: Syntax error on line 4 of /etc/apache2/sites-enabled/000-default.conf:
Invalid command ‘Action’, perhaps misspelled or defined by a module not included in the server configuration
Action ‘configtest’ failed.
The Apache error log may have more information.
Скажите есьт вариант для Ubuntu 16
А что у вас не получается в ней?
Андрей, добрый день, мне нужно развернуть веб сервер
на ubuntu 16 или 18 php5.2 b mysql на apache . Пытался делать как у вас написано, но не вышло на этапе make…делаю в AWS. также там минимальная версия mysql 5.6. в итоге сервер не пошел..я не сильный специалист в backend…тот инстанс уже терминировал…могу все попробовать заново, с учетом ошибок которые описаны в комментариях, если они не учтены конечно.