Установка PHP-5.3 \ php-fpm из сырцов и настройка

Дата Автор cdb19 комментариев

Данная статья устарела, оставлена исключительно для желающих покомпилировать php. Остальным людям предлагаю поставить php5.5 из репозитария, т.к. в нем он относительно свежий и телодвижений требуется совершить меньше.


Еще одна вкусняшка в нашем VDS — это php, который мы сейчас поставим. Ставить будем из сырцов, т.к. необходим нам именно php5.3 и никак не хуже, а в официальном репозитарии его еще нет. Действия описанные ниже будут произведены на ubuntu 10.04 LTS и скорее всего подойдут для php будущих версий (циферки только меняйте).
Как я уже писал — php у нас будет запускаться через php-fpm в chroot. В php5.3 официально включен php-fpm, поэтому веселые развлечения с патчами остались в прошлом.

Подготовка

Сначала ставим пакеты, необходимые для компиляции пхп:

sudo apt-get install autoconf2.13 libssl-dev libcurl4-gnutls-dev libjpeg62-dev libpng12-dev  libmysql++-dev libfreetype6-dev libt1-dev libc-client-dev mysql-client libevent-dev libxml2-dev libtool libmcrypt-dev

А еще нам потребуется checkinstall для автоматической сборки пакетов:

sudo apt-get install checkinstall

Сходите на сайт php.net/downloads.php, выберите себе последний и получите заветную ссылку. Смотрим внимательно на циферки в URL файла — в нем указана версия php. Возможно вам придется подправить все ниже описанные пути под эти циферки. В данной шпоре я буду описывать установку php-5.3.8. Итак, качаем php:

cd /usr/local/src
sudo wget -O ./php-5.3.8.tar.gz http://ru.php.net/get/php-5.3.8.tar.gz/from/ru2.php.net/mirror

Распаковываем php:

sudo tar xvfz php-5.3.8.tar.gz
sudo rm ./php-5.3.8.tar.gz

Сборка
Конфигурируем будующую сборку:

cd /usr/local/src/php-5.3.8
sudo ./configure --enable-fpm --with-mcrypt --enable-mbstring --with-openssl --with-mysql --with-mysql-sock --with-gd --with-jpeg-dir=/usr/lib --enable-gd-native-ttf  --with-pdo-mysql --with-libxml-dir=/usr/lib --with-mysqli=/usr/bin/mysql_config --with-curl --enable-zip  --enable-sockets --with-zlib --enable-exif --enable-ftp --with-iconv --with-gettext --enable-gd-native-ttf --with-t1lib=/usr --with-freetype-dir=/usr --prefix=/usr/local/php --with-fpm-user=www-data –with-fpm-group=www-data --with-fpm-conf=/usr/local/php/etc/php-fpm.conf --with-config-file-path=/usr/local/php/etc

Компилируем и устанавливаем получившийся пакет PHP:

sudo checkinstall --type=debian --default

Теперь при желании удалить PHP можно одной строкой (при установке хостинга это делать не надо):

sudo dpkg -r php

Настройка PHP
Настроим автозапуск php-fpm. Есть два пути:
1. Со стандартным скриптом запуска php (идет в составе с php и глючит — позволяет несколько раз запустить родительский процесс со всеми чилдами).

sudo cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm

2. Со сторонним скриптом (взят мной где-то не помню где и допилен под конкретные нужды — работает без глюков):

sudo wget -O /etc/init.d/php-fpm http://daily-notes.ru/files/2011/10/php-fpm

Выставим права скрипту на запуск и добавим в автозагрузку.

sudo chmod 755 /etc/init.d/php-fpm
sudo update-rc.d -f php-fpm defaults

Теперь надо создать файлы конфигурации. Можно пойти двумя путями — скопировать дефолтный конфиг php для продакшина или написать свой собственный по желанию. Первый вариант:

sudo cp php.ini-production /usr/local/php/etc/php.ini

Второй вариант — создать ручками файл /usr/local/php/etc/php.ini с примерно следующим содержимым:

[PHP]
asp_tags = Off
safe_mode = Off
safe_mode_gid = Off
expose_php = Off
y2k_compliance = On
allow_url_include = Off

[date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = "Asia/Novosibirsk"
; http://php.net/date.default-latitude
date.default_latitude = 55.016666
; http://php.net/date.default-longitude
date.default_longitude = 82.933333
; http://php.net/date.sunrise-zenith
;date.sunrise_zenith = 90.583333
; http://php.net/date.sunset-zenith
;date.sunset_zenith = 90.583333

В первом случае я не знаю что там по умолчанию наконфигурировано, но можно предположить что там «все как надо» 😉 Во втором случае я настраивал именно то что мне необходимо. Настройку дат конфигурировал для Новосибирска, для других регионов настройка date другая. Если эту секцию не заполнить — php будет ошибками забивать лог-файлы. Поддерживаемые зоны можно найти здесь http://www.php.net/manual/ru/timezones.php
Выставим права на конфиг php:

sudo chmod 644 /usr/local/php/etc/php.ini

Настройка PHP-FPM

Как я уже писал в прошлом опусе — у нас будет определенная структура папок для каждого сайта и php каждого из них будет работать в chroot. Для этого каждому сайту мы сделаем по конфигу (я же сделаю для примера только один для сайта koteika.ru).
Создадим папку, в которой будут размещаться конфиги php-fpm для сайтов:

sudo mkdir /usr/local/php/etc/pools

Создадим дефолтный файл-инклюд /usr/local/php/etc/default-config.conf с содержанием:

pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500
pm.status_path = /status

listen.backlog = -1
listen.owner = nginx
listen.group = nginx
listen.mode = 0600

ping.path = /ping
ping.response = pong

request_terminate_timeout = 0
request_slowlog_timeout = 0
catch_workers_output = yes
php_flag[display_errors] = Off
php_flag[display_startup_errors] = Off
php_admin_value[memory_limit] = 64M
php_admin_value[upload_max_filesize] = 32M
php_admin_value[post_max_size] = 40M

Небольшие комментарии к написаному:
pm — динамическое кол-во обработчиков php.
pm.max_children — максимальное число запущеных (лучше выставлять осознанно, чтобы не уйти в своп).
pm.start_servers — кол-во запускаемых обработчиков на старте php-fpm.
pm.min_spare_servers — минимальное число пустующих обработчиков (на случай если нагрузка начнет резко рости).
pm.max_spare_servers — максимальное число пустующих обработчиков (чтобы сильно много памяти лишний раз не занимать).
pm.max_requests — перезапускать обработчик через каждые N запросов (на случай утечки памяти и прочих глюков).

php_flag[display_errors] = Off — по умолчанию отключаем отображение ошибок php на всех сайтах.
php_flag[display_startup_errors] = Off — по умолчанию отключаем отображение ошибок php при запуске на всех сайтах.
php_admin_value[memory_limit] = 64M — по умолчанию на всех сайтах лимит используемой памяти — 64МБ.
php_admin_value[upload_max_filesize] = 32M — по умолчанию разрешаем загрузку файлов размером до 32МБ.
php_admin_value[post_max_size] = 40M — максимальный размер поста по умолчанию до 40МБ.

Теперь настало время главного конфига php-fpm — создаем файл /usr/local/php/etc/php-fpm.conf со следующим содержанием:

[global]
pid = run/php-fpm.pid
error_log = log/php-fpm.log
log_level = warning
emergency_restart_threshold = 5
emergency_restart_interval = 1m
process_control_timeout = 5s
daemonize = yes

include = etc/pools/*.conf

Пара комментариев:
log_level — означает уровень логирования. Бывает alert, error, warning, notice, debug. В случае непонятных багов-глюков-и.т.д выставляем в debug и читаем логи.
include — подключаем наши конфиги из папки pools.

Теперь создадим конфиг php-fpm для нашего сайта /usr/local/php/etc/pools/koteika.ru.conf с примерно следующим содержанием:

[koteika.ru]
include = etc/default-config.conf

user = koteika.ru
group = koteika.ru
listen = /home/koteika.ru/tmp/php-fpm.sock

request_terminate_timeout = 30s ; 30 sec for work
request_slowlog_timeout = 5s ; add to slowlog after 5 sec

slowlog = /home/koteika.ru/logs/slow.log
chroot = /home/koteika.ru
chdir = /public_html

php_flag[display_errors] = Off
php_flag[display_startup_errors] = Off

php_admin_value[error_log] = /home/koteika.ru/logs/php_error.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 64M
php_admin_value[upload_tmp_dir] = /home/koteika.ru/tmp

Здесь все более менее понятно:
[koteika.ru] — имя нашей секции вокеров (должно быть уникально для каждого конфига).
include — подключаем наш дефолтный конфиг, все настройки следующие за этой директивой перекрываются (странно, но user и group перекрыть не удалось).
user — юзер, от которого будет запущен процесс php.
group — группа, от которой будет запущен процесс php.
listen — тот самый сокет, котрый мы указывали в конфигурации nginx.
request_terminate_timeout — убъется, если зависнет более чем N сек.
chroot — путь, который будет казаться корнем для php.
chdir — по дефолту на старте php будет сначала открывать эту папку (тут для нашего конфига ничего менять не нужно).
В строках 15-21 подсветил перекрытие настроек из конфига-инклюда (переопределяйте при необходимости и добавляйте свои). php_admin_value[upload_tmp_dir] — папку загрузки тоже перекрываем в tmp нашего окружения chroot.

Так же можно перекрыть pm.max_children и прочие настройки количества обработчиков. Если сайт на VDS планируется один — можно всю память отдать ему (выставить 10-15 обработчиков на 512МБ тарифном плане). Так же следует подкрутить pm.start_servers, pm.min_spare_servers и pm.max_spare_servers к более разумному числу. Если сайтов планируется несколько — разумнее было бы раздать память сайтам исходя из важности и нагрузки. Для более полного понимания процесса настройки рекомендую почитать дефолтный файл конфигурации, который будет доступен тут — /usr/local/src/php-5.3.8/sapi/fpm/php-fpm.conf

Готовим окружение для chroot
Осталось совсем немного до счастливого запуска php. Структуру папок для нашего сайта мы создали в посте про конфигурацию nginx. Теперь осталось скопировать некоторые файлы, которые потребуются php для работы в chroot:

sudo cp /etc/resolv.conf /home/koteika.ru/etc
sudo cp /etc/nsswitch.conf /home/koteika.ru/etc

Файлы надо именно скопировать, создание хардлинков недопустимо. Причина — при возможном повышении привелегий пользователя до рута (вдруг каким-то образом оно случится) злоумышленик может поменять содержимое файлов (например resolv.conf) и заставить весь сервер делать запросы на подставной неймсервер, который может уже манипулировать вашим сервером в своих нуждах. Теперь наверное понятно зачем мы ставили кеширующий неймсервер на локалхост? 🙂
Копируем необходимые для php установленные библиотеки (версии поглядите у себя в папке ls /lib/libnss_dns*) и создаем симлинки на сами библиотеки:

sudo cp /lib/libnss_dns-2.11.1.so /home/koteika.ru/lib
sudo ln -s libnss_dns-2.11.1.so libnss_dns.so.2
sudo mv ./libnss_dns.so.2 /home/koteika.ru/lib

sudo cp /lib/libnss_files-2.11.1.so /home/koteika.ru/lib
sudo ln -s libnss_files-2.11.1.so libnss_files.so.2
sudo mv ./libnss_files.so.2 /home/koteika.ru/lib

Ну вот и все, запускаем сервис php-fpm:

sudo service php-fpm start

Если сервис не запустился, смотрим логи по адресу /usr/local/php/var/log/php-fpm.log. Возможно предется поменять log_level на debug в главном конфиге php-fpm.

Проверка
Создадим файл /home/koteika.ru/public_html/i.php с содержимым:

< ?php echo phpinfo(); ?>

Откроем файл в браузере http://koteika.ru/i.php — если все работает, то увидем информацию о php. После этого стоит удалить файл /home/koteika.ru/public_html/i.php.

P.S. Почта через mail в таком php пока не работает, но можно слать через SMTP — никто не запрещает. Позже мы допилим php до варианта, чтобы mail тоже работало.

Если вам понравилась моя статья, пожалуйста, не поленитесь кликнуть любую кнопочку ниже, или кинуть ссылку на статью в свой блог или форум. Всегда рад ответить на ваши вопросы в комментариях. Спасибо 🙂

  1. Настроим автозапуск php-fpm. Есть два пути:
    1. Со стандартным скриптом запуска php (идет в составе с php и глючит – позволяет несколько раз запустить родительский процесс со всеми чилдами).

    Лекарство:
    копируем оригинальный скрипт:
    sudo cp /usr/local/src/php-5.3.8/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
    добавляем
    if [ -r $php_fpm_PID ] ; then
    echo "pid file found - php-fpm is running ?"
    exit 1
    fi

    сразу после
    case "$1" in
    start)
    echo -n "Starting php-fpm "

    в файле /etc/init.d/php-fpm

    проблема исчерпана.

  2. Для lemb

    Лекарство не сработало!
    После первого же ребута VPS, вылеченный по Вашей методе php-fpm приказал долго жить… Пользую второй вариант.

    • По подробней узнать как именно приказал долго жить?
      У меня уже не первый месяц на сервере именно этот скрипт -проблем с ним не было (хотя были: перезагрузки, остановки сервера вплоть до его падения).
      PHP-FPM всегда стартует должным образом.

  3. Подскажите , у меня не подгружаеться php.ini. Собирал по интсрукциям с другого сайта — по наблюдениям все тоже, но вместо checkinstall — make & make test & make install. Настраивал по вашим инструкциям. Заключение о том, что php.ini не подгружается сделал по наличию ошибок от php date и отсутствию записей о eaccelerator (настраивал тоже по вашей инструкции)

    • Нашел:
      при сборке не установил опции
      —with-config-file-path=/usr/local/php/etc
      поэтому конфиги ищет в /usr/local/php/lib/
      исправил с помощью:
      ln -s /usr/local/php/etc/php.ini /usr/local/php/lib/

  4. ubuntu 12.04 32

    либы /lib/libnss_dns*

    находятся по таким путям

    /usr/arm-linux-gnueabihf/lib/libnss_dns-2.15.so
    /usr/arm-linux-gnueabihf/lib/libnss_dns.so.2
    /usr/arm-linux-gnueabihf/lib/libnss_files-2.15.so
    /usr/arm-linux-gnueabihf/lib/libnss_files.so.2

  5. Sry za translit..
    Vtoroj den uze seksom zanimajus s «checkinstall»
    vo vremja etoj proceduri rugaetsa raz 200 — ne mogu udlit katalog `’:
    i posle nee, pri zapuske «dpkg -r php» govorit 4to nekotorie katalogi ne pustie.. i delaet «abort»

    root@ubuntu-gl:/usr/local/src/php-5.4.12# dpkg -r php
    (Reading database … 62099 files and directories currently installed.)
    Removing php …
    dpkg: warning: while removing php, directory ‘/usr/local/php/include/php’ not empty so not removed.
    dpkg: warning: while removing php, directory ‘/usr/local/php/lib/php/.registry’ not empty so not removed.

    vse delal pod root (4erez sudo -s)

    tak ze eso naril paru veshej iz «checkinstall»
    PEAR package PHP_Archive not installed: generated phar will require PHP’s phar extension be enabled.

    You probably don’t want them to be included in the package,
    especially if they are inside your home directory.
    Do you want me to list them? [n]: n
    Should I exclude them from the package? (Saying yes is a good idea) [y]: y

    • checkinstall от рута запускали ?
      dpkg -r он вроде не удаляет папки если туда кто-то навалил после вас… хз почему, но вдруг какой пакет туда проставился, чтобы не поломать его.

        • Ну если не дает удалить каталог — значит очевидно прав нет. Значит наверное надо выдать права ? Может вы ставите пхп в папку в которой он уже стоит ? Попробуйте sudo su и через него потом все сделать. Странно конечно, такое впечатление что вы не root…

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *