Вместо предисловия

Я делал много кратких заметок-набросков по поводу настройки разынх серверов под проекты на 1С-Битрикс. По сути, я тестировал производительность конфигураций в различных дистрибутивах и связках. И понял, что для средненагруженных проектов удобнее использовать один сервер под все сразу (Apache, MySQL, PHP). Это будет самая последняя и самая полная статья в серии как настроить все с нуля.

Цель:

Создать сервер для хостинга проектов на 1С-Битрикс.

Оборудование:

CPU: Intel® Xeon® E3-1245 (Quad-Core)
RAM: 16 GB DDR3 RAM ECC
HDD: 2 x 3 TB SATA 6 Gb/s HDD 7200 rpm (RAID 1)

ОС:

Debian 6 (64bit), чистая минимальная установка

Оглавление

1. Начальная настройка и подготовка сервера
2. Установка Apache, MySQL, PHP
3. Настройка Apache
4. Настройка MySQL
5. Настройка PHP
6. Настройка FTP
7. Настройка iptables
8. Оптимизация

1. Начальная настройка и подготовка сервера

Меняем время на нужное для нас

# rm /etc/localtime
# ln -s /usr/share/zoneinfo/Europe/Moscow /etc/localtime

Убаждаемся, что команда hostname выдает правильное имя сервера. Это же имя должно быть в файле /etc/hosts напротив IP-адреса. Если такоего нет, задаем:

# hostname www.vcore.ru

Файл /etc/hosts:

127.0.0.1 localhost
5.9.94.197  www.vcore.ru

Для начала добавляем репозитории, откуда будут браться пакеты. Их два — репозиторий Zend и репозиторий, откуда мы будем устанавливать MySQL версии 5.5
В файл /etc/apt/sources.list добавляем следующие строчки:

## Zend Server
deb http://repos.zend.com/zend-server/deb server non-free
## MySQL Server 5.5
deb http://packages.dotdeb.org squeeze all
deb-src http://packages.dotdeb.org squeeze all

Добавляем ключи репозиторием:

# wget http://repos.zend.com/zend.key -O- |apt-key add -
# wget http://www.dotdeb.org/dotdeb.gpg -O- |apt-key add -

Обновляем установленные пакеты (если есть такие):

# apt-get update
# apt-get upgrade

 

2. Установка Apache, MySQL, PHP

Ставим сразу все. Это все одна длинная-длинная строчка.

# apt-get install zend-base libapache2-mod-php-5.3-zend-server php-5.3-xmlrpc-zend-server php-5.3-optimizer-plus-zend-server php-5.3-zem-zend-server php-5.3-curl-zend-server php-5.3-data-cache-zend-server php-5.3-mbstring-zend-server php-5.3-mcrypt-zend-server php-5.3-memcache-zend-server php-5.3-mysql-zend-server php-5.3-mysqli-zend-server php-5.3-gd-zend-server php-5.3-ctype-zend-server php-5.3-json-zend-server php-5.3-dev-zend-server mysql-server

Я не стал ставить phpmyadmin, потому что не хочу давать напрямую доступ к базе. Любую работу с БД можно производить через панель управления Битрикс, а администратору проще все делать через консоль.

3. Настройка Apache

Все настройки сайтов будут храниться в папке /etc/apache2/sites-enabled/

Там уже есть один сайт по умолчанию 000-defaul. Я создаю сайты по следующему принципу -. Т.е. все сайты с индексом 000 — это сайты, которые принадлежат владельцу сервера. Сайты с индексом 001 — это первый клиент, 002 — второй клиент и т.д. — это… как ни странно… домен.

Я покажу пример настройки двух своих сайтов. Файлы одинаковые, за исключением переменных ServerName, ServerAlias, DocumentRoot и директории сайта. Так же, надо помнить, что для Битрикс надо устанавливать значение AllowOverride All, чтобы обрабатывались файлы .htaccess.

/etc/apache2/sites-enabled/000-default:

<VirtualHost *:80>
        ServerName www.vcore.ru
        ServerAlias vcore.ru
        ServerAdmin [email protected]

        DocumentRoot /var/www/vcore.ru/
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/vcore.ru/>
                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
        LogLevel error
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

/etc/apache2/sites-enabled/000-shieldz.ru:

<VirtualHost *:80>
        ServerName www.shieldz.ru
        ServerAlias shieldz.ru
        ServerAdmin [email protected]

        DocumentRoot /var/www/shieldz.ru/
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/shieldz.ru/>
                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
        LogLevel error
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Сами сайты хранятся в папке /var/www/
Устанавливаем права:

# chown -R www-data:www-data /var/www/*
# chmod -R 755 /var/www/*

Если вы работаете с файлами сайта через консоль, то владельцем файла или папки становитс тот пользователь, от которого вы работаете. После внесения любых изменений в файлы сайта, лучше заново выполнять команду chown.

Пока что на этом все. Apache запускать еще рано. Не торопимся.

4. Настройка MySQL

Тип всех таблиц в базах данных я устанавливаю в InnoDB, соответственно файл конфигурации будет приведен под максимальную производительность именно InnoDB, а не MyISAM.

Первое, что необходим сделать — это обезопасить базу данных. Пароль администратора спрашивался в процессе установки. Нам остается лишь выполнить следующую команду, которая предложит сменить пароль администратора, удалить временные базы и пользователей, а так же запретит удаленное подключение пользователю root.

# mysql_secure_installation

К сожалению, база данных уже будет запущена. Почему к сожалению? Потому что дальше будет ошибка.
А пока что заходим в бд и убеждаемся, что нет записей с пустыми паролями

# mysql -u root -p
> USE mysql;
> SELECT host, user, password FROM user;

Если есть пустые пароли, меняем их

> SET PASSWORD FOR '<пользователь>'@'<хост>' = PASSWORD('<пароль>');

Далее, нам надо создать файл конфигурации. За основу берем файл my-huge.cnf, которые доступен в качестве примера в документации к MySQL. Забираем этот файл.

# cd /usr/share/doc/mysql-server-5.5/examples/
# gunzip my-huge.cnf.gz
# cp my-huge.cnf /etc/mysql/my.cnf

Файл /etc/mysql/my.cnf (с комментариями в ключевых моментах):

port = 3306 socket = /var/run/mysqld/mysqld.sock [mysqld] port = 3306 socket = /var/run/mysqld/mysqld.sock skip-external-locking # задаем максимальное число подключений # я бы не стал задавать больше 300, если вы не знаете зачем это max_connections = 250 # со всеми этими параметрами можно поиграть для улучшения производительности # для меня эти работают наиболее удачно # в основном они относятся к таблицам MyISAM, а не InnoDB key_buffer_size = 64M thread_stack = 128K max_allowed_packet = 1M table_open_cache = 64M join_buffer_size = 8M sort_buffer_size = 8M read_buffer_size = 8M read_rnd_buffer_size = 8M myisam_sort_buffer_size = 64M thread_cache_size = 16 query_cache_size = 128M query_cache_limit = 1M # судя по тестам, значение в 2000 является наиболее удачным table_cache = 2048 # Количество ядер процессора умножаем на 2 thread_concurrency = 8 # рекомендация Битрикс transaction-isolation = READ-COMMITTED # указываем, что хотим по умолчанию использовать innodb default-storage-engine = innodb # кодировка по умолчанию character-set-server = utf8 collation-server = utf8_general_ci innodb_data_home_dir = /var/lib/mysql innodb_data_file_path = ibdata1:2000M;ibdata2:10M:autoextend innodb_log_group_home_dir = /var/lib/mysql # выставляем значение где-то 50 - 80 % от объема оперативной памяти innodb_buffer_pool_size = 4G innodb_additional_mem_pool_size = 20M # не более 25 % от размера innodb_buffer_pool_size innodb_log_file_size = 256M innodb_log_buffer_size = 8M # рекомендация Битрикс innodb_flush_log_at_trx_commit = 2 # рекомендация Битрикс innodb_flush_method = O_DIRECT innodb_lock_wait_timeout = 50 [mysqldump] quick max_allowed_packet = 16M [mysql] no-auto-rehash [myisamchk] key_buffer_size = 256M sort_buffer_size = 256M read_buffer = 2M write_buffer = 2M [mysqlhotcopy] interactive-timeout

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

Останаливаем сервер БД и удаляеем следующие файлы:

# /etc/init.d/mysql stop
# rm /var/lib/mysql/ib*
# /etc/init.d/mysql start

Все. На этом настройки сервера баз данных завершились. Напоследок, если вы все же решились работать с базами данных через консоль, а не через phpmyadmin, то вот несколько полезных команд.

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

# mysql -u root -p

Создание базы данных:

> CREATE DATABASE <имя бд>;

Назначение прав на базу данных (обращаем внимание на кавычки):

> GRANT ALL PRIVILEGES ON <имя бд>.* TO '<имя пользователя>'@'localhost' IDENTIFIED BY '<пароль>';
> FLUSH PRIVILEGES;

Восстановление базы данных из бекапа (эта команда выполняется просто из консоли):

# mysql -u root -p <имя бд> < <файл.sql>

 

5. Настройка PHP

Настроек PHP не так уж и много. Выполняем рекомендации и требования 1С-Битрикс и делаем следующие изменения в файле /usr/local/zend/etc/php.ini:

allow_call_time_pass_reference = On
realpath_cache_size = 4096K
upload_max_filesize = 20M
date.timezone = "Europe/Moscow"

Перезагружаем веб-сервер:

# /etc/init.d/apache2 restart

 

6. Настройка FTP

Устанавливаем ProFTPD

# apt-get install proftpd

В файле /etc/proftpd/proftpd.conf я лишь внес следующие изменения:

ServerName                      "vCore LTD FTP Server"

RootLogin                       off
MaxLoginAttempts                5
AllowRetrieveRestart            on
AllowStoreRestart               on
DirFakeGroup                    on
tcpNoDelay                      on
DeleteAbortedStores             on
AllowForeignAddress             on

UseReverseDNS                   off

RequireValidShell               off

PassivePorts                    49152 49155

Как создавать пользователей? Легко, командой useradd
-d — домашнаяя директория пользователя (т.е. то, где находится сайт)
-g — группа, к которой принадлежит пользователь
-M — не надо создавать домашнюю директорию
-N — не создавать одноименную группу с именем пользователя

# useradd -d /var/www/vcore.ru -g www-data -M -N vcore

Далее задаем пароль для созданного пользователя

# passwd vcore

 

7. Настройка iptables

Создаем файл /etc/iptables.rules со следующим содержанием:

*filter

# Разрешаем любой траффик на интерфейс lo0, а весь траффик 127/8 блокируем, если он не идет черерз lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -i ! lo -d 127.0.0.0/8 -j REJECT

# Пропускаем установленные входящие
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Разрешаем любой исходящий
-A OUTPUT -j ACCEPT

# Разраешаем HTTP и HTTPS
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

# Разрешаем SSH
# --src 123.123.123.123 - это адрес, откуда пускать ssh, можно указать несколько адресов через запятую
-A INPUT -p tcp -m state --state NEW --dport 22 --src 123.123.123.123 -j ACCEPT

# Разрешаем FTP
# можно использовать --src, как и в предыдущем примере, если пускать надо лишь с определенных адресов
-A INPUT -p tcp -m state --state NEW --dport 21 -j ACCEPT
-A INPUT -p tcp -m state --state NEW --dport 49152 -j ACCEPT
-A INPUT -p tcp -m state --state NEW --dport 49153 -j ACCEPT
-A INPUT -p tcp -m state --state NEW --dport 49154 -j ACCEPT
-A INPUT -p tcp -m state --state NEW --dport 49155 -j ACCEPT

# Разрешаем пинг
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

# Заносим в лог всё запрещенное
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

# Запрещаем все остальное (политика "запрещаем все, если не указано иначе")
-A INPUT -j REJECT
-A FORWARD -j REJECT

COMMIT

Далее, чтобы правлиа заработали выполняем следующую команду:

# iptables-restore < /etc/iptables.rules

 

Оптимизация

Самый большой прирост в производительности (по крайней мере в мониторе производительности в Битрикс) дает включение APC-кеша. Для этого надо в файле bitrix/php_interface/dbconn.php добавить следующие строчки:

define("BX_CACHE_TYPE", "apc");
define("BX_CACHE_SID", $_SERVER["DOCUMENT_ROOT"]);