Шукати в цьому блозі

вівторок, 16 червня 2009 р.

Установка Nginx + PHP5 (С FastCGI и XCache) + MySQL

Как только вы начинаете чувствовать нагрузку на свой купленный за 5 долларов в месяц сервер, то читая статьи на тему «Когда стоит переходить на VPS», подумывайте о покупке чего-нибудь более серьёзного. И как только это «более серьёзное» находится в вашем распоряжении, перед вами открывается целая вселенная, когда всё зависит только от вас и вариантов развития событий миллионы. Вы – администратор виртуального (или физического) сервера.
Эта статья предназначена в первую очередь начинающим админам, желающим без многочасового поиска по Сети сделать всё быстро и правильно. Поэтому не будем откладывать и начнём.

Для начала несколько допущений, чтобы потом не возникло вопросов.
  • Apache хороший сервер, особенно если вы ставите его только на обработку скриптов и не загружаете отдачей статики. При правильной настройке с ним можно творить чудеса. Но я принципиально отказался от его использования, так как настроить один сервер проще и быстрее чем два, а в случае с Apache нам понадобится ещё один.
  • Я использую Nginx как полноценную замену Apache. Он лёгкий, настраиваемый, мощный. Хорошо работает с Drupal. Но это абсолютно не значит, что вы не можете использовать Lighttpd. Просто поищите тогда другую статью :)
  • Операционная система, на которой производилась инсталляция - Ubuntu Hardy LTS (поддержка до 2013 года). Если вы используете другую – вам не нужно искать другую статью, просто у вас будет немного отличаться синтаксис запуска программ. Например, вместо aptitude будете использовать apt-get, yum, и т.д. Читайте документацию к вашей системе. Однако по большей части на любых Linux системах мой мануал сработает. Любители ./configure, make, make install , порадуются только один раз.
  • Виртуальный сервер куплен у компании Slicehost. Бесподобная поддержка, куча образовательных материалов на все случаи жизни, и очень демократичные цены (20$ за VPS c 256MB оперативы), плюс – идеология Слайсхоста заставит вас забыть о том, что такое Cpanel, Plesk и прочие костыли для управления хостингом. Вы будете делать всё сами, ни от кого не зависеть, тотальная свобода для творчества и работы! В общем, сначала попробуйте, а потом вы останетесь у них навсегда ;) Кстати, зарегистрировавшись по моей реферальной ссылке, вы получите круглосуточную поддержку ещё и от меня.
Итак, помним, что в итоге мы должны получить HTTP сервер Nginx + PHP5 (С Fast-cgi и XCache) + MySQL на Ubuntu Hardy LTS.

Первоначальная настройка сервера

Нет, ребята, так дело не пойдёт, настолько я распыляться не буду. Идём сюда и делаем как написано. Настроить сервер – значит установить файрвол, создать юзеров для доступа по SSH, отключить учётную запись root, раскрасить bash, проапдейтить пакеты до последних версий. Просто следуйте простым инструкциям здесь и здесь. Всё очень доступно.

Установка PHP, MySQL и необходимых пакетов

  • Устанавливаем необходимые пакеты (Build Essentials)
sudo aptitude install build-essential
  • Устанавливаем PHP c клиентом. И без Apache!
sudo aptitude install php5-common php5-dev php5-mysql php5-sqlite php5-tidy php5-xmlrpc php5-xsl php5-cgi php5-mcrypt php5-curl php5-gd php5-mhash php5-pspell php5-snmp php5-sqlite libmagick9-dev php5-cl
Возможно, я несколько перебрал с пакетами, но некоторые из них вам могут понадобиться в дальнейшем, они не занимают много места, поэтому абсолютно не помешают.
  • Устанавливаем MySQL сервер
    sudo aptitude install mysql-server mysql-client libmysqlclient15-dev
  • Защищаем его от недоброжелателей
mysql_secure_installation
Конечно, MySQL – вещь сложная в настройке, и какой бы ни был у вас сервер, вам придётся потратить много времени на её оптимизации. Рекомендую после того, как разберётесь с сервером, начать тюнинг MySQL c помощью этого скрипта.

Установка и настройка сервера Nginx

Существуют миллионы инструкций как компилировать программы из исходников, но мне не хочется этим заморачиваться. К тому же Ubuntu позволяет проделывать такие вещи.
sudo aptitude install nginx
Всё, а вы ещё что-то ожидали? Эта строка установит сам сервер и основные зависимости. После этого вам остаётся только запустить его и проверить, всё ли работает.
sudo /etc/init.d/nginx start
Затем наберите в браузере IP (или URL) вашего сервера и насладитесь простым, но очень значимым для нас приветственным экраном Nginx.
nginx_welcome_screen
На этом этапе рекомендуется откинуться на спинку кресла, отдохнуть минут 10, или выпить чаю-кофе. Ваш сервер уже официально в Интернете. В принципе, вы уже можете разместить на нём сайт (только не на PHP, хотя мы его вроде и ставили). Для удовольствия – попробуйте залить туда пару страничек HTML.
Действительно, куда залить?
По умолчанию после установки сервера вышеописанным способам дефолтный хост ведёт в папку на сервере /var/www/nginx-default. Мы это сможем легко поменять уже через несколько минут.
Помните, что контролируется Nginx тремя командами:
sudo /etc/init.d/nginx start

sudo /etc/init.d/nginx stop

sudo /etc/init.d/nginx restart
Однако последнюю (рестарт) использовать не рекомендую, это не Apache. Получите больше головной боли. Поэтому для перезапуска сервера сначала останавливаем его, а потом запускаем. Если не запускается – значит отлаживаем конфигурацию – обычно он довольно понятно говорит, где ошибка.
Также важной частью является первоначальная настройка сервера, откройте файл /etc/nginx/nginx.conf и вставьте в него всё, что находится здесь:

user www-data www-data;
worker_processes 2;

error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

access_log /var/log/nginx/access.log;

sendfile on;
#tcp_nopush on;

#keepalive_timeout 0;
keepalive_timeout 3;
tcp_nodelay off;

gzip on;
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml
application/xml+rss text/javascript;

include /etc/nginx/sites-enabled/*;

}

Таким образом мы сразу настроили сжатие сервером данных, выключили некоторые функции и включили некоторые важные. Потом вы сможете настроить его под свои нужды более точно, но пока нам нужна лишь работающая конфигурация.
А сейчас создадим грамотный лэйаут для наших будущих сайтов. В принципе – абсолютно не важно, где будет лежать ваш сайт, но более-менее стандартным является размещение сайтов в каталоге /home/user/public_html, где user – это пользователь системы с необходимыми правами. (как создать юзера и назначить права почитайте по ссылкам в начале мануала, если вы этого ещё не сделали)
Если же юзер только один (а зачастую это только вы), то можно сделать просто
sudo mkdir /home/public_html


sudo mkdir -p /home/public_html/mydomain.com/{public,private,log,backup}

Таким образом мы создали структуру папок для нашего будущего сайта mydomain.com. Файлы, доступные из Сети будут лежать в папке /public, логи в папке /log, остальное понятно.
Создаём виртуальный хост – файл, который будет указывать домену, где лежит наш сайт.
sudo nano /etc/nginx/sites-available/mydomain.com
Затем вставляем в него следующий текст конфига, естественно, заменяя структуру папок и название домена на ваши.
Внимание! Этот конфиг учитывает некоторые особенности Drupal, например, файловую структуру, крон, а также наличие модулей Imagecache, Fckeditor, Backup and Migrate. Если вы используете другие системы, просто удалите или закомментируйте ненужные части конфига, они подписаны. Если же вы ищете в сети решение проблем работы Drupal c Imagecache или Fckeditor, то вы его уже нашли :)

server {
listen 80;
server_name mydomain.com www.mydomain.com;
access_log /home/public_html/mydomain.com/log/access.log;
error_log /home/public_html/mydomain.com/log/error.log;

root /home/public_html/mydomain.com/public;

charset utf-8;

location = / { rewrite . /index.php last; }
location / { rewrite ^(.*)$ /index.php?q=$1 last; }
location = /index.php {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME /home/public_html/mydomain.com/public$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
# To retrieve this script periodically use: curl -sH "Host: my.host.tld" http://localhost/cron.php
location = /cron.php {
allow 127.0.0.1;
deny all;
fastcgi_pass 127.0.0.1:8521;
include /etc/nginx/fastcgi_params;
}
# Static content
location = /robots.txt { if (-f $document_root/sites/default/robots.txt) { rewrite . /sites/default/robots.txt$
location ~ ^(/sites/all)?/(modules|themes)/.*.(css|js|png|gif|jpg)$ { break; }
location /misc/ { break; }
location /sites/all/modules/fckeditor { break; }
location /files/ { break; } # Depending on Drupal configuration (Administer -> File system)

# Imagecache (http://drupal.org/project/imagecache)
location /files/imagecache/ {
if (-f $request_filename) { break; }
rewrite ^(.*)$ /index.php?q=$1 last;
}

# **** Comment out this location after installing/updating Drupal ****
# location ~ ^/(install|update).php$ {
# allow 172.22.11.2;
# deny all;
# fastcgi_pass 127.0.0.1:8521;
# include /etc/nginx/fastcgi_params;
# }
# ********************************************************************

# hide protected files
location ~* .(engine|inc|info|install|module|profile|po|sh|.*sql|theme|tpl(.php)?|xtmpl)$|^(code-style.pl|Entri$
deny all;
}

# hide backup_migrate files
location ~* ^/files/backup_migrate {
deny all;
}

}

И активизируем сайт:
sudo ln -s /etc/nginx/sites-available/mydomain.com /etc/nginx/sites-enabled/mydomain.com
А сейчас внимание! В конфиг включены правила для создания чистых ссылок (clean urls) для системы Drupal, если вы используете Wordpress или другие системы, вам необходимо поискать на сайтах поддержки правила создания чистых ссылок для nginx. Это займёт лишних 5 минут, особенно если ваша система популярная. Впрочем, она может работать и с моим конфигом :)
Помните, файл .htaccess под Nginx не работает! Все директивы вставляются в конфигурацию сервера или виртуального хоста!
Таким образом, спорная часть это
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php?q=$1 last;
}
Остальные части конфига необходимы!
В конфиге мы попросили Nginx слушать FastCGI на 9000 порту, поэтому – если у вас стоит файрвол, не забудьте открыть этому порту доступ (как и порту 3306 для MySQL)

Запуск PHP как FastCGI процесса

Я не профессиональный администратор, поэтому ищите в Гугле подробные объяснения тому, что мы сейчас будем делать.
Дело в том, что нам необходимо заставить наш сервер работать с PHP, чего он по умолчанию делать вовсе не обязан (в настоящее время в Nginx анонсирована только тестовая поддержка Perl). Поэтому для взаимодействия сервера с языком программирования мы используем специальный протокол, или интерфейс – FastCGI. Это своеобразный мостик для обеспечения взаимопонимания между Nginx и PHP. И сейчас мы будем “учить” их работать вместе.
Мы уже устанавливали php5-cgi, если вы помните, теперь нам нужно каким-то образом запускать FastCGI процесс. Есть несколько способов сделать это. Мы будем использовать специальную программку spawn-fcgi, которая до недавнего времени шла в комплекте с другим сервером – Lighttpd. Сейчас она идёт как отдельный проект и расположена по адресу http://redmine.lighttpd.net/projects/spawn-fcgi
Мы же используем старый проверенный вариант “выдирания” её из Lighttpd. Это даст мне уверенность в том, что это точно будет работать у вас. Чуть позже я изменю эту часть статьи, но только когда сам всё сделаю на практике.
Итак
mkdir ~/sources

cd ~/sources


wget http://www.lighttpd.net/download/lighttpd-1.4.19.tar.bz2

tar jxvf lighttpd-1.4.19.tar.bz2
Не знаю, необходимы или нет эти зависимости, но установочный скрипт ругается, поэтому давайте лучше их установим:
sudo aptitude install libpcre3-dev libbz2-dev
Далее – скомпилируем Lighttpd, но не будем его устанавливать, нам нужна только одна программка. Поэтому делаем следующее:
cd lighttpd-1.4.19

./configure

make
Потом идём пить кофе, потому что на экране будет много всего, производящего впечатление на девушек :) Безобразие на экране будет длиться минуты 3-4.
Затем берём исходники spawn-fcgi, и кладём их в то место, где им и полагается быть:
sudo cp src/spawn-fcgi /usr/bin/spawn-fcgi
Далее, если это программа, то нам нужен скрипт, чтобы запускать её:
sudo nano /usr/bin/php-fastcgi
Затем копируем в скрипт следующие строки:

#!/bin/sh
/usr/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -u www-data -g www-data -f /usr/bin/php5-cgi
А теперь внимание! В Интернете, насколько мне известно, вы можете найти другие варианты синтаксиса этой строки, где www-data присутствует только один раз. Настоятельно рекомендую вам воспользоваться именно моим вариантом, так как это позволит вам в будущем избежать неприятностей и ошибки PHP – No input file specified. Отличие моего варианта от распространённого в том, что мы указываем не только пользователя, но и группу. Если они у вас отличаются, то просто замените на ваши данные. Самое интересное, что на одном сервере у меня сработало только с юзером, а на другом – нет. Поэтому будьте внимательны!
Строка, которую мы ввели, означает, что каждый раз, когда скрипт будет вызываться, процесс fcgi будет запущен на порту 9000 для пользователя www-data в группе www-data (это дефолтные пользователь и группа, устанавливаемые при первоначальной настройке системы).
Нам осталось только разобраться, как запускать этот скрипт при запуске FastCGI.
sudo nano /etc/init.d/init-fastcgi
Получаем пустой экран, и вставляем в него:

#!/bin/bash
PHP_SCRIPT=/usr/bin/php-fastcgi
RETVAL=0
case "$1" in
start)
$PHP_SCRIPT
RETVAL=$?
;;
stop)
killall -9 php5-cgi
RETVAL=$?
;;
restart)
killall -9 php5-cgi
$PHP_SCRIPT
RETVAL=$?
;;
*)
echo "Usage: php-fastcgi {start|stop|restart}"
exit 1
;;
esac
exit $RETVAL
Опять же внимание! В Сети вы найдёте слегка изменённый вариант скрипта управления запуском FastCGI, где будет killall -9 php, вместо killall -9 php5-cgi. В моём случае работал только последний вариант, то есть в скрипт надо вставлять точное название процесса, который мы запускаем. Честно говоря, я вообще удивляюсь, как у людей работает без этого. Но мы же делаем всё правильно, не так ли!
Дальше – у нас ничего не будет работать, пока мы не сделаем два предущие скрипта исполняемыми. Для этого вводим следующее:
sudo chmod 755 /usr/bin/php-fastcgi

sudo chmod 755 /etc/init.d/init-fastcgi
Ну что ж, сейчас можно смело запускать наш FastCGI:
sudo /etc/init.d/init-fastcgi start
Вы должны получить что-то вроде информации о том, что spawn-fcgi успешно запустился как процесс.
А для того, чтобы всё работало после перезагрузки набираем:
sudo update-rc.d init-fastcgi defaults
И, я надеюсь, вы не забыли запустить Nginx :) С этого момента вам придётся постоянно помнить, что сейчас вам нужно запускать и сервер и FastCGI.
В принципе, это всё!

Тестирование, отладка. Установка XCache.

Так, давайте проверим, работает ли PHP как fast-cgi процесс:
ps ax | grep php
Если появился список запущенных процессов, значит всё ОК.
А чтобы проверить, подключён ли PHP к Nginx, создайте файл info.php в веб-директории вашего домена mydomain.com, вставьте туда:
< ? echo phpinfo(); ?>
А затем запустите его из браузера. Получите исчерпывающую информацию о том, как работает ваш PHP, какие модули загружены.
А сейчас давайте ускорим исполнение PHP скриптов путём кэширования бинарного кода. Вы можете установить любой акселератор, но я выбираю XCache.
Установка XCache:
sudo aptitude php5-xcache
Особенностью этого акселератора является то, что его надо вручную подключать к php.ini, и там же конфигурировать под свои нужды.
Открываем:
sudo nano /etc/php5/cgi/php.ini
Проматываем этот длиннющий файл до самого конца, попутно настраивая его под себя. Например, вы можете изменить значение memory_limit на большее (хотя бы до 64MB, особенно если работаете с Drupal). Для прокрутки используете Ctrl+V.
В конце файла вставляем:

[xcache-common]
extension = xcache.so
[xcache.admin]
xcache.admin.user = "mOo"
; xcache.admin.pass = md5($your_password)
xcache.admin.pass = ""
[xcache]
; ini only settings, all the values here is default unless explained
; select low level shm/allocator scheme implemenation
xcache.shm_scheme = "mmap"
; to disable: xcache.size=0
; to enable : xcache.size=64M etc (any size > 0) and your system mmap allows
xcache.size = 64M
; set to cpu count (cat /proc/cpuinfo |grep -c processor)
xcache.count = 4
; just a hash hints, you can always store count(items) > slots
xcache.slots = 8K
; ttl of the cache item, 0=forever
xcache.ttl = 0
; interval of gc scanning expired items, 0=no scan, other values is in seconds
xcache.gc_interval = 0
; same as aboves but for variable cache
xcache.var_size = 64M
xcache.var_count = 1
xcache.var_slots = 8K
; default ttl
xcache.var_ttl = 0
xcache.var_maxttl = 0
xcache.var_gc_interval = 300
xcache.test = Off
; N/A for /dev/zero
xcache.readonly_protection = Off
; for *nix, xcache.mmap_path is a file path, not directory.
; Use something like "/tmp/xcache" if you want to turn on ReadonlyProtection
; 2 group of php won't share the same /tmp/xcache
; for win32, xcache.mmap_path=anonymous map name, not file path
xcache.mmap_path = "/dev/zero"
; leave it blank(disabled) or "/tmp/phpcore/"
; make sure it's writable by php (without checking open_basedir)
xcache.coredump_directory = ""
; per request settings
xcache.cacher = On
xcache.stat = On
xcache.optimizer = On
[xcache.coverager]
; per request settings
; enable coverage data collecting for xcache.coveragedump_directory and xcache_coverager_start/stop/get/clean() functions (will hurt executing performance)
xcache.coverager = Off
; ini only settings
; make sure it's readable (care open_basedir) by coverage viewer script
; requires xcache.coverager=On
xcache.coveragedump_directory = ""

Обратите внимание на строку, где надо указать количество ядер в вашем процессоре. У меня их 4. Там же написано как это узнать, если не уверены.
Также здесь вы можете установить логин и пароль для управления скриптом. Если с логином всё понятно, то пароль должен быть зашифрован с помощью md5. Чтобы правильно установить пароль, создайте в веб-директории файл test.php, и поместите в него следующую строку:
< ?php echo md5("вашпароль"); ?>
Запустив его, вы получите ваш пароль в зашифрованном виде, его то и надо вставлять в php.ini. Не вставляйте в php.ini “человеческий пароль”!
Чтобы получить доступ к веб-интерфейсу XCache, нам придётся скачать исходники отсюда и достать из них папку xcache/admin/ (всю папку), затем загрузить её в веб-директорию, и зайти в неё со своим логином и паролем, установленным в php.ini.
Затем можете наслаждаться тем, как будет летать ваш сервер после установки акселератора.

Немає коментарів: