настройка Apache 2 + PHP5

для хостинга клиентских сайтов

Постановка задачи: Заказчик арендует (покупает) выделенный сервер, помещает его в ЦОДе провайдера и хочет разместить на нём несколько своих сайтов.

Предположим, что используя КВМ - Вы уже установили linux (в данном случае ставится Debian Squeeze), а также ssh и ftp и базу данных MySQL. В этой статье мы установим:

  • Apache 2 — веб-сервер;
  • PHP 5 — язык программирования, используемый для создания веб-приложений.

Итак, приступаем к настроке web-сервера - Apache 2:

Примечание: Обязательно обновите свой source лист и пакеты, уже установленные в системе:

server:/# apt-get update && apt-get upgrade

1. Установка сервера Apache2 и интерпретатора PHP5

Устанавливаем веб сервер Apache2 и интерпретатор PHP5:

server:/# apt-get install apache2 apache2-doc php5 libapache2-mod-php5

Что не версия, то расположение и подход к конфигурированию сервиса apache2 и структуры/положения конфигурационных файлов чуть-чуть да меняют. В любом случае идут верным путем, отделяя "мух от котлет" и используют модульную структуру конфигурирования. Такой подход позволяет настраивать поэтапно:

  1. 1. Настройку пакетов расширений php - графических пакетов, авторизации, работы с СУБД, отладчиков;
  2. 2. Глобальные настройки, языковые настройки, настройки prefork, worker, event для нагруженных решений, сайтов и порталов;
  3. 3. Настройку непосредственно доменов и субдоменов, распологаемых на нашем выделенном сервере в любое время и в любом порядке.

Конфигурационные файлы Apache находятся в папке /etc/apache2, а папка вашего веб-сайта по умолчанию /var/www. Но обо всем по порядку.

2. Установка расширений для языка PHP, конфигурирование службы

Зачем это надо? Ну например - Вас замучил СПАМ! Хотите использовать капчу (CAPTCHA, картинка для роботов) для защиты от нежелательной корреспонденции или защитить свой форум от роботов-регистраторов? Тогда Вам потребуется поддержка в языке программирования php методов работы с графическими изображениями, пакет php-gd. Пришло время установить необходимые php-расширения, чтобы наш сервер мог обслуживать современные сайты и технологии. Установим необходимые (и не очень) пакеты расширений:

server:/# apt-get install php5-gd php5-dev libapache2-mod-php5 php-auth php5-geoip php5-imagick php5-sasl php5-curl php5-mcrypt php5-memcached php-pear php5-xdebug 

Если уже уставнолена СУБД, то крайне не помешают пакеты:

server:/# apt-get install php5-sqlite php5-mysql  libapache2-mod-auth-mysql php5-interbase 

Слегка скорректируем настройки PHP, изменив в файле /etc/php5/apache2/php.ini следующие директивы:

error_reporting = E_ALL
post_max_size = 32M
allow_url_fopen = Off
upload_tmp_dir = /var/tmp
upload_max_filesize = 100M

Настроим теперь пакет XDebug, который лежит в /usr/lib/php5/20090626+lfs/ Скорее всего последняя директория будет отличаться. Открываем 20-xdebug.ini:

server:/# vim /etc/php5/apache2/conf.d/20-xdebug.ini

zend_extension=/usr/lib/php5/20100525+lfs/xdebug.so
xdebug.remote_enable=1
;директория для сохранения результатов профилировщика
xdebug.profiler_output_dir=/home/yourhome/projects/tmp_xdebug 

Подключение механизма Mod Rewrite посредством директив .htaccess

Mod_rewrite предоставляет механизм динамического изменения запрашиваемых URL-ов. Так называется дополнительный модуль для популярного веб-сервера Apache, доля которого на рынке веб-серверов составляет порядка 60-70%. Для включения mod_rewrite, достаточно чтобы модуль mod_rewrite.so был загружен в Apache. Этот модуль содержится в стандартной поставке сервера. Но как правило, он обычно отключен.

Нижеследующая команда включает за нас модуль mod_rewrite в состав веб-сервера, обслуживающего Ваш веб-сайт, и допускается использование его директив в файлах .htaccess. Дополнительно задействуем модули expires и headers

server:/# a2enmod rewrite expires headers

Enabling module rewrite.
Enabling module expires.
Enabling module headers.
To activate the new configuration, you need to run:
  service apache2 restart

Перезапустим службу apache2 для вступления изменений в силу

server:/# service apache2 restart

Чтобы проверить корректность установленного php и его модулей-расширений, переименовываем файл /var/www/index.html в index.php

 
server:/# mv /var/www/index.html /var/www/index.php
server:/# vim /var/www/index.php 

...и добавляем в него небольшой php-код содержащий вызов функции phpinfo():

<?php 
      phpinfo(); 
?>  

Готово! Посещаем тестовую страницу http://ip.address/test.php или http://domain/test.php и этот скрипт выдаст вам массу информации об используемых модулях php.

Примечание: Не оставляйте общедоступным скрипт содержащий вывод функции phpInfo() - после того, как Вы убедились что сервер сконфигурирован верно, удалите эту страницу или вызов этой функции.

3. Конфигурация сервера apache2

Вначале внесем необходимые измения в конфигурацию нашего сервера apache 2. Выясним в какой конфигурации работает наш сервер

server:/# apache2 -V 
... 
Server version: Apache/2.2.22 (Debian)
Server MPM:     Prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....

Имеем установленный по умолчанию режим Prefork MPM. В первую очередь проверим и скорректируем файл глобальных наcтроек сервера - /etc/apache2/apache2.conf:

KeepAlive on
KeepAliveTimeout 5

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule mpm_prefork_module>
    StartServers          8
    MinSpareServers       8
    MaxSpareServers       15
    MaxClients            250
    MaxRequestsPerChild   10000
</IfModule>

# worker MPM
# StartServers: initial number of server processes to start
# MaxClients: maximum number of simultaneous client connections
# MinSpareThreads: minimum number of worker threads which are kept spare
# MaxSpareThreads: maximum number of worker threads which are kept spare
# ThreadLimit: ThreadsPerChild can be changed to this maximum value during a
#              graceful restart. ThreadLimit can only be changed by stopping
#              and starting Apache.
# ThreadsPerChild: constant number of worker threads in each server process
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule mpm_worker_module>
    StartServers          2
    MinSpareThreads      25
    MaxSpareThreads      75 
    ThreadLimit          64
    ThreadsPerChild      25
    MaxClients          150
    MaxRequestsPerChild   0
</IfModule>

# event MPM
# StartServers: initial number of server processes to start
# MaxClients: maximum number of simultaneous client connections
# MinSpareThreads: minimum number of worker threads which are kept spare
# MaxSpareThreads: maximum number of worker threads which are kept spare
# ThreadsPerChild: constant number of worker threads in each server process
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule mpm_event_module>
    StartServers          2
    MaxClients          150
    MinSpareThreads      25
    MaxSpareThreads      75 
    ThreadLimit          64
    ThreadsPerChild      25
    MaxRequestsPerChild   0
</IfModule>

Тэг(опция): MaxClients

Директива MaxClients устанавливает максимальное количество параллельных запросов, которые будет поддерживать сервер. Apache не будет порождать больше процессов/потоков чем MaxClients. Значение MaxClient не долно быть слишком маленьким (иначе много клиентов останутся необслуженными), но и не стоит устанавливать слишком большое количество - лучше не обслужить часть клиентов чем исчерпать все ресурсы, залезть в своп и умереть под нагрузкой.

Хорошим может быть значение MaxClients = количество памяти выделенное под веб-сервер / максимальный размер порожденного процесса или потока. Для статических файлов apache использует около 2-3 Мб на процесс, для динамики (php, cgi) - зависит от скрипта, но обычно около 16-32 Мб.Если сервер уже обслуживает MaxClients запросов, новые запросы попадут в очередь, размер которой устанавливается с помощью директивы ListenBacklog.

Тэг(опция): MinSpareServers, MaxSpareServers, и StartServers

Т.к. создание потока, и особенно процесса - дорогая операция, apache создает их заранее. Директивы MaxSpareServers и MinSpareServers устанавливают как много процессов/потоков должны ожидать в готовности принять запрос (максимум и минимум). Если значение MinSpareServers слишком маленькое и неожиданно приходит много запросов, apache вынужден будет создавать много новых процессов/потоков, что создаст дополнительную нагрузку в этой стрессовой ситуации. С другой стороны, если MaxSpareServers слишком велико, apache будет сильно нагружать систему этими процессами, даже если количество клиентов минимально.

Постарайтесь установить такие MinSpareServers и MaxSpareServers, чтобы apache не создавал более 4 процессов/потоков в секунду. Если он создаст более 4, в ErrorLog будет помещено сообщение об этом. Это - сигнал того что MinSpareServers слишком мало.

Тэг(опция): MaxRequestsPerChild

Директива MaxRequestsPerChild устанавливает сколько запросов может обработать один дочерний процесс/поток прежде чем он будет завершен. По умолчанию значение этой директивы установлено в 0, что означает что однажды созданный процесс/поток не будет завершен никогда (ну кроме случаев остановки сервера или краха этого процесса/потока).

Рекомендую установить MaxRequestsPerChild равное какому-нибудь достаточно большому числу (несколько тысяч). Это не создаст излишней нагрузки, связаной с тем что apache будет вынужден создавать новые дочерние процессы, в то же время это поможет избавиться от проблем с утечкой памяти в дочерних процессах (что очень возможно например если вы используете нестабильную версию php).

Тэг(опция): KeepAlive и KeepAliveTimeout

KeepAlive позволяет делать несколько запросов в одном TCP-подключении. Это особенно полезно для html-страниц с большим количеством изображений. Если KeepAlive установлен в Off, то для самой страницы и для каждого изображения будет создано отдельное подключение (которое нужно будет обработать master-процессу), что плохо и для сервера и для клиента. Так что для подобных случаев рекомендуется устанавливать KeepAlive в On.

Для других применений (например для download-сервера) KeepAlive может быть бесполезен и даже вреден, т.к. при включенном KeepAlive сервер закрывает соединение не сразу, а ждет KeepAliveTimeout секунд нового запроса. Для того чтобы процессы не висели слишком долго в бесполезном ожидании, устанавливайте KeepAliveTimeout достаточно малым, около 5-10 секунд обычно достаточно.

Файл /etc/apache2/conf.d/charset

Раскомментируем кодировку UTF-8, или заменим её на Windows-1251, в зависимости от выбора кодировки по-умолчанию для нашего сервера в целом:

 
AddDefaultCharset Windows-1251 

Файл /etc/apache2/sites-available/default

Внесем необходимые исправления в "домен по умолчанию". В начале файла добавляем опции ServerAdmin и ServerName и указываем в них основной сайт (по умолчанию)на сервере и почту администратора.

Изменяем положение корня "сайта по умолчанию" DocumentRoot с /var/www/ на /var/www/public_html, а также исправляем <Directory /var/www> на <Directory /var/www/public_html>. Не забудьте создать эту директорию:

server:/# mkdir /var/www/public_html

Чтобы директивы mod_rewrite можно было использовать на всех сайтах нашего выделенного сервера, необходимо в этом файле (в соответствующем разделе "<Directory /путь/до/директории>") прописать: AllowOverride all. Обязательно поправим опцию AllowOverride в настройках директории /var/www/public_html, изменив её с значения None на All. Остальное можно не трогать.

<VirtualHost *:80>
	ServerAdmin webmaster@demon.by
	ServerName demon.by

	DocumentRoot /var/www/public_html
	<Directory />
		Options FollowSymLinks
		AllowOverride None
	</Directory>
	<Directory /var/www/public_html/>
		Options Indexes FollowSymLinks MultiViews
		AllowOverride All
		Order allow,deny
		allow from all
	</Directory>
	
	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
	<Directory "/usr/lib/cgi-bin/">
		AllowOverride None
		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
		Order allow,deny
		Allow from all
	</Directory>
	
	ErrorLog ${APACHE_LOG_DIR}/error.log
	
	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel warn
	
	CustomLog ${APACHE_LOG_DIR}/access.log combined
	
</VirtualHost>

Примечание: Если при использовании файлов .htaccess появляется ошибка 403 ДОСТУП ЗАПРЕЩЕН ("permission denied") - установите разрешения 644 на эти файлы:

server:/# find /var/www -type f -name '.htaccess' -exec chmod 644 {} \;

4. Файловая структура папок для типового хостинга

Теперь создадим клиентские сайты на нашем сервере. Рассмотрим на примере. Создадим недостающие папки и расставим нужные права. Используется следующая струкутра, так как не использую никаких ISP панелей:

-<- /var/www -----------------------------------------------v>¬
¦                  Name                 ¦ Size  ¦   MTime     ¦
¦/..                                    ¦UP--DIR¦             ^
¦/cgi-bin                               ¦    512¦Oct 27 12:01 ¦
¦/backups                               ¦   1024¦Oct 27 12:01 ¦
¦/logs                                  ¦   3584¦Oct 27 12:01 ¦
¦/public_html                           ¦    512¦Oct 27 12:03 ¦
¦/tmp                                   ¦    512¦Oct 27 12:03 ¦
¦/vhosts                                ¦    512¦Oct 27 12:02 ¦
¦ index.php                             ¦     21¦Oct 27 12:24 ¦
+-------------------------------------------------------------v

Это корневая папка сервера DocumentRoot - здесь я располагаю служебный сайт сервера и специльное ПО - postfixadmin, squirelmail, awstats и проч. Папка public_html остаётся "папкой для сервера default" (сервера по умолчанию) Теперь рассмотрим содержимое папки vhosts:

-<- /var/www/vhosts ---------------------------------------v>¬
¦                 Name                 ¦ Size  ¦   MTime     ¦
¦/..                                   ¦UP--DIR¦             ^
¦/site1.ru                             ¦    512¦Oct 27 12:24 *
¦/site2.ru                             ¦    512¦Oct 27 12:04 ¦
¦/example.com                          ¦    512¦Oct 27 12:04 ¦
¦/subdomain.example.com                ¦    512¦Oct 27 12:04 ¦
¦/site4.ru                             ¦    512¦Oct 27 12:04 ¦
+------------------------------------------------------------v

И наконец содержимое папки любого виртуального хоста:

-<- /var/www/vhosts/example.com ---------------------------v>¬
¦                 Name                 ¦ Size  ¦   MTime     ¦
¦/..                                   ¦UP--DIR¦             ^
¦/backups                              ¦    512¦Oct 27 12:04 *
¦/cgi-bin                              ¦    512¦Oct 27 12:01 ¦
¦/logs                                 ¦    512¦Oct 27 12:04 ¦
¦/public_html                          ¦    512¦Oct 27 12:04 ¦
¦/tmp                                  ¦    512¦Oct 27 12:04 ¦
¦ .privsite                            ¦      0¦Oct 27 12:24 ¦
+------------------------------------------------------------¦

Примечание: Из особеностей назначения прав:

Папки сайтов, находящиеся в vhosts должны иметь владельца proftpd и группу www-data, разрешение 755

server:/# chown -v www-data:proftpd /var/www/vhosts/*
server:/# find /var/www/ -type d -name 'public_html' -exec chmod 775 {} \;

Папки tmp должны иметь владельца и группу root и разрешение 777

    server:/# find /var/www/ -type d -name 'tmp' -exec chmod 777 {} \;

Файлы .htaccess должны иметь владельцом root и разрешение 644

server:/# find /var/www/ -type f -name '.htaccess' -exec chmod 644 {} \;

Группа proftpd необходима для организации к папкам клиентских сайтов доступа по FTP. Для продвинутых рекомендую, не заводя нового пользователя в системе, использовать цифровую нотацию групп/пользователей в настройках службы proftpd и назначать конкретные права этому пользователю для конкретной пользовательской папки. Как факультатив)

Как вы устроите свой хостинг - решать Вам. Я делаю структуру удобную мне и моим клиентам. Для всех виртуальных хостов будет создан виртуальный пользователь и настроен доступ по ftp к корневой папке хоста (например example.com). Этот подход позволяет дать возможность клиентам иметь доступ к резервным копиям (бэкапам, backups), лог-файлам своего сайта и создавать выше корня public_html защищенные папки (например, cgi-bin) и системные файлы с паролями для авторизации htaccess (пример, .privsite)

5. Создание хостинга виртуального домена example.com на базе сервера Apache2

Теперь добавим новый файл конфигурации для домена example.com в папке sites-available:

 
server:/# vim /etc/apache2/sites-available/example.com

# Config virtual host for example.com
<VirtualHost *:80>
   ServerName example.com
   ServerAlias www.example.com
   ServerAdmin admin@example.com

   ScriptAlias /cgi/ /var/www/vhosts/example.com/cgi
   ScriptAlias /cgi-bin/ /var/www/vhosts/example.com/cgi-bin

   DocumentRoot /var/www/vhosts/example.com/public_html

   <Directory "/var/www/vhosts/example.com/public_html/">
	   Options Indexes FollowSymLinks ExecCGI
	   AllowOverride All
	   Order allow,deny
	   Allow from all
   </Directory>

   php_admin_flag register_globals Off
   php_admin_flag magic_quotes_gpc Off
   php_admin_flag safe_mode_gid On
   php_admin_flag output_buffering On
   php_admin_value open_basedir /var/www/vhosts/example.com/public_html
   php_admin_value safe_mode_include_dir /var/www/vhosts/example.com/public_html
   php_admin_value safe_mode_exec_dir /noexec
   php_admin_value doc_root /var/www/vhosts/example.com/public_html
   php_admin_value upload_tmp_dir /var/www/vhosts/example.com/tmp
   php_admin_value session.save_path /var/www/vhosts/example.com/tmp
   ErrorLog /var/www/vhosts/example.com/logs/example-error.log
   CustomLog /var/www/vhosts/example.com/logs/example-access.log common

</VirtualHost>

В этом файле мы описали домен example.com с отдельными, обособленными от общего сервера, настройками. Теперь "включаем" этот домен:

 
server:/# a2ensite example.com

Скопируем наш файл для тестов в папку /var/www/vhosts/example.com/public_html:

 
server:/# cp /var/www/index.php /var/www/vhosts/example.com/public_html/index.php

Проверим настройки и перезапутим апач:

server:/# apache2ctl -t
Syntax OK

server:/# apache2ctl restart

Проверяем информацию о сайте в браузере - http://example.com

Примечание: Можно отлаживать работу сервера и своих сайтов не имея записей в ДНС или не настраивая свой личный ДНС-сервер. Для этого используются файлы существующие в любой системе - hosts. Их расположение:

  • c:\WINDOWS\system32\drivers\etc\hosts - Windows
  • /etc/hosts - *nix, FreeBSD

Этот файл может содержать адреса и псевдонимы для локальных узлов или узлов в пределах локальной сети. Прежде чем обратиться к службе ДНС Ваш компьютер просматривает этот файл на предмет совпадения пар ip-адрес - доменное имя. Добавьте Ваши сайты в этот файл, связав их с адресом настраиваемого сервера (10.6.10.123):

127.0.0.1	localhost
10.6.10.123	example.com
10.6.10.123	www.example.com
10.6.10.123	subdomain.example.com

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

Мы закончили настраивать наш выделенный сервер. В любом случае, если что-то не работает проверям логи и включаем мозги.

Комментарии

Комментарии отключены, сожалеем