В репозитарии ubuntu 14.04 LTS лежит относительно свежий php5.5.9, который не долго думая мы и поставим. Как я уже писал — php5 у нас будет запускаться через php-fpm в chroot.
sudo apt-get install php5-fpm php5-gd php5-mysqlnd php5-memcache php5-memcached php5-xcache sudo update-rc.d -f php5-fpm defaults sudo apt-get install memcached
Тут ставится php-cli, php-fpm, клиентские модули для доступа к memcached, модуль xcache (кеширование опкодов php), клиентский модуль для доступа к mysql. Далее php-fpm добавляется в автозагрузку. Так же устанавливается memcached.
Настройка PHP
Для начала удалим из конфига Zend Opcache. Всем он хорош, но именно из-за него некоторые мои сайты иногда причудливо глючат на ровном месте. Вместо него у нас будет работать xcache. Итак удаляем:
sudo rm -f /etc/php5/cli/conf.d/05-opcache.ini sudo rm -f /etc/php5/fpm/conf.d/05-opcache.ini
Предупрежу сразу — при обновлении php через apt-get ссылки на эти конфиги будут регулярно добавляться, т.ч. вам будет необходимо их опять удалять и перезагружать php.
Теперь надо создать файлы конфигурации php. Можно пойти двумя путями — скопировать дефолтный конфиг php для продакшина или написать свой собственный по желанию. Первый вариант:
sudo cp /usr/share/php5/php.ini-production /etc/php5/fpm/php.ini sudo cp /usr/share/php5/php.ini-production.cli /etc/php5/cli/php.ini
Второй вариант — создать ручками файл /etc/php5/fpm/php.ini с примерно следующим содержимым:
[PHP] asp_tags = Off safe_mode = Off expose_php = Off 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 [Session] session.save_handler = memcache session.save_path = "127.0.0.1:11211" session.use_cookies = 1 session.auto_start = 0 session.name = session session.serialize_handler = php session.gc_probability = 0 session.gc_divisor = 1000 session.gc_maxlifetime = 1440 session.cache_limiter = nocache session.cache_expire = 300
В первом случае я не знаю что там по умолчанию наконфигурировано, но можно предположить что там «все как надо» 😉 Во втором случае я настраивал именно то что мне необходимо. Настройку дат конфигурировал для Новосибирска, для других регионов настройка date другая. Если эту секцию не заполнить — php будет ошибками забивать лог-файлы. Поддерживаемые зоны можно найти здесь http://www.php.net/manual/ru/timezones.php. Сессии будут сохраняться в memcached, это мы прописываем в конфиге php. Размеры и расположение memcached сервера можно указать в его конфиге /etc/memcached.conf — по умолчанию там 64MB на стандартном порту.
Выставим права на конфиг php:
sudo chmod 644 /etc/php5/fpm/php.ini
Настройка PHP-FPM
Как я уже писал в прошлом опусе — у нас будет определенная структура папок для каждого сайта и php каждого из них будет работать в chroot. Для этого каждому сайту мы сделаем по конфигу (я же сделаю для примера только один для сайта koteika.ru). Конфиги php-fpm для сайтов размещаются в папке /etc/php5/fpm/pool.d. Создадим конфиг koteika.ru.conf следующего содержания:
[koteika.ru] prefix = /home/$pool user = koteika.ru group = koteika.ru listen = /home/$pool/tmp/php5-fpm.sock listen.owner = nginx listen.group = nginx listen.mode = 0600 pm = dynamic pm.max_children = 10 pm.start_servers = 4 pm.min_spare_servers = 2 pm.max_spare_servers = 6 pm.max_requests = 1000 pm.status_path = /status ping.path = /ping ping.response = pong ;access.log = log/$pool.access.log ;slowlog = log/$pool.log.slow chroot = /home/$pool chdir = /public_html catch_workers_output = yes php_flag[display_errors] = Off php_flag[display_startup_errors] = Off php_admin_value[error_log] = /home/$pool/logs/php_error.log php_admin_flag[log_errors] = on php_admin_value[memory_limit] = 64M php_admin_value[max_execution_time] = 120 php_admin_value[post_max_size] = 64M php_admin_value[upload_max_filesize] = 48M php_admin_value[upload_tmp_dir] = /home/$pool/tmp php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -f info@koteika.ru
Небольшие комментарии к написаному:
[koteika.ru] — имя пула вокеров (должно быть уникально для каждого конфига), оно же может подставиться в некоторые пути как переменная. Подробнее смотрите дефолтный конфиг, который идет в качестве примера php-fpm.
user — юзер, от которого будет запущен процесс php.
group — группа, от которой будет запущен процесс php.
listen — тот самый сокет, котрый мы указывали в конфигурации nginx.
request_terminate_timeout — убъется, если зависнет более чем N сек.
chroot — путь, который будет казаться корнем для php.
chdir — по дефолту на старте php будет сначала открывать эту папку.
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[post_max_size] = 64M — максимальный размер поста до 64МБ (не забываем разрешить такой же размер post-запроса в конфигурации nginx — client_max_body_size.
php_admin_value[upload_max_filesize] = 48M — разрешаем загрузку файлов размером до 48МБ, это значение по логике должно быть меньше предыдущего (при отправке файлов они вроде входят в тело post-запроса).
Если сайт на VDS планируется один — можно всю память отдать ему. Так же следует подкрутить pm.start_servers, pm.min_spare_servers и pm.max_spare_servers к более разумному числу. Если сайтов планируется несколько — разумнее было бы раздать память сайтам исходя из важности и нагрузки. Для более полного понимания процесса настройки рекомендую почитать дефолтный файл конфигурации.
Готовим окружение для 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 установленные библиотеки и создаем симлинки на сами библиотеки:
sudo mkdir /home/koteika.ru/lib/x86_64-linux-gnu sudo cp /lib/x86_64-linux-gnu/libnss_dns-2.19.so /home/koteika.ru/lib/x86_64-linux-gnu sudo ln -s libnss_dns-2.19.so libnss_dns.so.2 sudo mv ./libnss_dns.so.2 /home/koteika.ru/lib/x86_64-linux-gnu sudo cp /lib/x86_64-linux-gnu/libnss_files-2.19.so /home/koteika.ru/lib/x86_64-linux-gnu sudo ln -s libnss_files-2.19.so libnss_files.so.2 sudo mv ./libnss_files.so.2 /home/koteika.ru/lib/x86_64-linux-gnu
Далее копируем остальные необходимые файлы и сертификаты:
sudo mkdir /home/koteika.ru/etc/ssl sudo cp -R /etc/ssl/certs /home/koteika.ru/etc/ssl/certs sudo mkdir /home/koteika.ru/usr/share sudo cp -R /usr/share/ca-certificates /home/koteika.ru/usr/share/ca-certificates sudo cp -R /usr/share/zoneinfo /home/koteika.ru/usr/share/zoneinfo
Создаем рандом (потребуется для https соединений из пхп):
sudo mknod /home/koteika.ru/dev/urandom c 1 9 sudo mknod /home/koteika.ru/dev/null c 1 3 sudo mknod /home/koteika.ru/dev/zero c 1 5 sudo chmod 666 /home/koteika.ru/dev/null /home/koteika.ru/dev/zero /home/koteika.ru/dev/urandom
Ну вот и все, запускаем сервис php-fpm:
sudo service php5-fpm start
Если сервис не запустился, смотрим логи по адресу /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 тоже работало.