Считаем железо: сколько ресурсов ест YetiForce на 20-50 пользователей
За пятнадцать с лишним лет аутсорсинга я усвоил простую вещь: любая история про «CRM тормозит» начинается не в интерфейсе, а на этапе выбора площадки. YetiForce — это полноценная PHP-система с базой MariaDB, php-fpm-пулом, фоновым планировщиком и почтовым сканером. Её нельзя оценивать как лёгкий лендинг. Поэтому первый разговор с клиентом у меня всегда про ресурсы, а не про кнопки.
Мы в ITfresh обслуживаем юрлица до 50 рабочих мест и держим собственные серверы в дата-центре МТС. За это время сложилась рабочая вилка, от которой я отталкиваюсь. Для коллектива в 10-15 активных пользователей достаточно 2 vCPU, 4 ГБ ОЗУ и небольшого NVMe-диска. Для типового отдела продаж на 20-50 человек беру 4 vCPU, 8 ГБ ОЗУ и 80 ГБ SSD NVMe — с запасом на вложения, письма и историю. Именно эта конфигурация закрывает 90% задач, с которыми ко мне приходят.

Почему я категорически против шаред-хостинга под YetiForce, даже когда клиент просит сэкономить? Причин несколько, и все они всплывают потом в самый неподходящий момент:
- Cron. Системе нужен планировщик, который запускается раз в минуту от имени веб-пользователя. На большинстве виртуальных хостингов вы получите в лучшем случае запуск раз в 5-15 минут, а часто и вовсе урезанный по времени выполнения. Без нормального крона половина функций мертва.
- Права и владелец файлов. YetiForce пишет в кэш, хранилище вложений и конфиг. На шареде вы не управляете владельцем процесса php и раскладкой прав так, как нужно.
- Свой php-fpm pool. Мне важно задать memory_limit, время выполнения и число воркеров под конкретную нагрузку. На общем хостинге эти параметры чужие и глобальные.
- Бэкапы и восстановление. На своей ВМ я снимаю снапшоты, дампы базы и архив файлов по расписанию и проверяю восстановление. На шареде бэкап — это чужая непрозрачная кнопка.
Поэтому решение однозначное: развернуть CRM на VPS или выделенной виртуальной машине. Мы ставим на свои ВМ в ЦОД МТС, но если у клиента есть площадка — работаем и на ней. Ниже приведу ориентировочные конфигурации, которые проверены на боевых внедрениях.
| Рабочих мест | vCPU | ОЗУ | Диск | innodb_buffer_pool_size | php-fpm воркеры |
|---|---|---|---|---|---|
| до 15 | 2 | 4 ГБ | 40 ГБ NVMe | 1 ГБ | 5-8 |
| 20-30 | 4 | 8 ГБ | 80 ГБ NVMe | 2-3 ГБ | 10-15 |
| 40-50 | 4-6 | 12-16 ГБ | 120 ГБ NVMe | 4-6 ГБ | 15-25 |
Диск берите с запасом: письма с вложениями, сканы договоров и история активностей растут незаметно, но неотвратимо. NVMe критичен именно из-за базы — YetiForce делает много мелких запросов, и на медленных дисках интерфейс начинает «залипать» при десятке одновременных пользователей.
Практика ITfresh: закладывайте память не только под php, но и под буферный пул MariaDB. Если innodb_buffer_pool_size меньше рабочего набора базы, диск будет молотить постоянно. На 8 ГБ ОЗУ я отдаю базе 2-3 ГБ, остальное — php-fpm и системе. Это простое правило снимает большинство жалоб на «тормоза».
Стек и версии: что именно ставить в 2026 году
Актуальный релиз на момент написания — YetiForce CRM 7.1.1 от 22 мая 2026 года, это последняя стабильная ветка семейства 7.x. Лицензия YetiForce Public License 7: для self-hosted-установки система бесплатна, и это одна из причин, по которой я рекомендую её клиентам, не желающим платить помесячно за облачные CRM.
Моя базовая связка под продакшен в 2026 году выглядит так: Debian 12 или Ubuntu 24.04 LTS в качестве ОС, nginx с php-fpm на PHP 8.3 и MariaDB как база данных. Windows под YetiForce я не ставлю — официально он не рекомендован, и на практике это лишние проблемы с правами, кроном и производительностью.
По PHP официально поддерживаются версии 8.1, 8.2 и 8.3, рекомендуется ветка 8.3.x. Формально добавлена поддержка 8.4 и частичная 8.5, но для боевой системы я осознанно беру именно 8.3 — она проверена и стабильна с расширениями. По базе рекомендована MariaDB 10.6 (не старше 10.1) либо MySQL 8.0.13 и новее. На Debian 12 и Ubuntu 24.04 удобнее всего ставить MariaDB 10.11 LTS — это свежее 10.6 и полностью допустимо.
Установку пакетов на Ubuntu 24.04 я обычно свожу к одной большой команде. Вот рабочий набор для стека nginx + php-fpm + MariaDB со всеми нужными расширениями:
sudo apt update && sudo apt install -y nginx mariadb-server php8.3-fpm php8.3-cli php8.3-common php8.3-mysql php8.3-imap php8.3-curl php8.3-gd php8.3-xml php8.3-mbstring php8.3-soap php8.3-zip php8.3-intl php8.3-bcmath php8.3-ldap php8.3-imagick php8.3-opcache php8.3-apcu php8.3-exif certbot python3-certbot-nginx git unzip
Разберём, что именно тянем и зачем. Обязательные для YetiForce расширения PHP: imap, PDO, pdo_mysql, mysqlnd, openssl, curl, gd, pcre, xml, json, session, dom, zip, mbstring, soap, fileinfo, iconv, intl, SPL, Reflection, SimpleXML, bcmath, filter, ctype, hash. Многие из них (json, pcre, session, dom, SPL, Reflection, filter, ctype, hash, openssl, iconv, SimpleXML) уже входят в ядро php8.3-cli/common, поэтому в apt-строке их отдельно нет. Опциональные, которые я всё равно ставлю на прод: exif, ldap, OPcache, apcu, imagick — они дают ускорение и интеграции.
Требования, о которых молчит README
Вот здесь начинается самое интересное. Веб-инсталлер YetiForce имеет строгий валидатор требований, который заваливает большинство самостоятельных установок. И причина обычно не в PHP-расширениях, а в настройках MariaDB и php.ini, о которых в кратких гайдах не пишут вовсе.
По базе есть три жёстких требования. Первое: SQL_MODE обязательно должен исключать STRICT_TRANS_TABLE и ONLY_FULL_GROUP_BY — иначе система будет спотыкаться на своих же запросах. Второе: движок по умолчанию — InnoDB. Третье: max_allowed_packet не меньше 128M, иначе крупные вложения и импорты будут обрываться. Плюс кодировка utf8mb4 и на уровне клиента, и на уровне сервера. Создаю отдельный конфиг MariaDB:
# /etc/mysql/mariadb.conf.d/99-yetiforce.cnf
[mysqld]
sql_mode = "ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
default_storage_engine = InnoDB
max_allowed_packet = 128M
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
innodb_buffer_pool_size = 2G
[client]
default-character-set = utf8mb4
Обратите внимание: в sql_mode я оставил безопасные флаги и убрал именно те два, что мешают YetiForce. После правки — systemctl restart mariadb.
По php.ini валидатор проверяет конкретные лимиты. Рабочие значения, которые проходят проверку и не жмут систему на вложениях: memory_limit=1024M, max_execution_time=600, post_max_size=100M, upload_max_filesize=100M, max_input_vars=10000. Правлю их в пуле php-fpm:
# /etc/php/8.3/fpm/conf.d/99-yetiforce.ini
memory_limit = 1024M
max_execution_time = 600
post_max_size = 100M
upload_max_filesize = 100M
max_input_vars = 10000
date.timezone = Europe/Moscow
Грабля из практики: в PHP есть два разных php.ini — для CLI и для FPM. Крон YetiForce работает через CLI, а веб-инсталлер читает настройки FPM. Правьте оба, иначе валидатор в браузере покажет зелёный статус, а фоновые задачи будут падать по памяти или таймауту. Проверяйте активные значения командой php-fpm8.3 -i | grep memory_limit и php -i | grep memory_limit раздельно.
По веб-серверу рекомендован nginx версии 1.23, но и штатный nginx из Ubuntu 24.04 отлично работает. Допустим и Apache 2.4 — но учтите, что модуль ModSecurity с YetiForce несовместим, и при харденинге на Apache его придётся отключать для виртуального хоста CRM.
Установка по шагам: от файлов до рабочего интерфейса
Когда стек готов и требования выполнены, сама установка YetiForce занимает меньше часа. Но дьявол в деталях — в правах на файлы и в том, как вы пройдёте валидатор. Разберём по порядку.

Скачиваем 7.1.1 и раскладываем права
Есть два пути: клонировать git-репозиторий или скачать готовый архив релиза с GitHub. Для продакшена я предпочитаю архив конкретной версии — так исключаю случайное обновление на нестабильный коммит. Git удобен, когда планируете следить за ветками, но тогда фиксируйте тег релиза.
# вариант с архивом релиза
cd /var/www
sudo mkdir -p yetiforce && cd yetiforce
sudo wget https://github.com/YetiForceCompany/YetiForceCRM/releases/download/7.1.1/YetiForceCRM-7.1.1.zip
sudo unzip YetiForceCRM-7.1.1.zip && rm YetiForceCRM-7.1.1.zip
# владелец — веб-пользователь
sudo chown -R www-data:www-data /var/www/yetiforce
sudo find /var/www/yetiforce -type d -exec chmod 755 {} \;
sudo find /var/www/yetiforce -type f -exec chmod 644 {} \;
Ключевой момент — владелец файлов. Весь каталог CRM должен принадлежать www-data (тот же пользователь, под которым крутится php-fpm), потому что система активно пишет в подкаталоги cache, storage и config. Если владелец будет root, инсталлер честно скажет, что не может записать конфиг, и остановится. Проверьте, что каталоги cache, storage и config доступны на запись веб-пользователю — это самая частая причина «красных строк» на первом экране.
Проходим веб-инсталлер и его валидатор требований
Дальше открываем сайт в браузере и попадаем в мастер установки. Первый экран — тот самый валидатор требований, который проверяет PHP-расширения, версию, лимиты и настройки базы. Если вы честно выполнили предыдущие разделы, большинство строк будут зелёными. Но разберём типовые красные строки, которые я вижу чаще всего, и как их чинить.
| Красная строка валидатора | Что означает | Как чинить |
|---|---|---|
| Missing PHP extension: imap | Не установлен php-imap — без него не работает почтовый модуль | apt install php8.3-imap, затем перезапуск php-fpm |
| SQL mode contains ONLY_FULL_GROUP_BY | В sql_mode остались запрещённые флаги | Убрать флаг в 99-yetiforce.cnf, перезапустить MariaDB |
| max_allowed_packet too low | Меньше 128M — крупные операции оборвутся | Выставить 128M в конфиге MariaDB |
| memory_limit below 1024M | PHP не хватит памяти на импорт и отчёты | Правим оба php.ini (FPM и CLI), перезапуск FPM |
| max_input_vars too low | Формы с большим числом полей обрежутся | Ставим 10000 в php.ini |
| Directory not writable: cache/storage | Неверный владелец каталогов | chown -R www-data:www-data на корень CRM |
Пройдя валидатор, мастер попросит данные подключения к базе. Заранее создаю отдельную базу и пользователя — не под root:
sudo mysql -e "CREATE DATABASE yetiforce CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
sudo mysql -e "CREATE USER 'yf_user'@'localhost' IDENTIFIED BY 'СЮДА_СЛОЖНЫЙ_ПАРОЛЬ';"
sudo mysql -e "GRANT ALL PRIVILEGES ON yetiforce.* TO 'yf_user'@'localhost';"
sudo mysql -e "FLUSH PRIVILEGES;"
Указываете эти реквизиты в мастере, задаёте логин и пароль администратора, выбираете отраслевой пресет данных (для типового отдела продаж беру базовый), и система разворачивает схему. На NVMe это занимает пару минут. После установки инсталлер сам подскажет удалить установочные файлы и настроить крон — про крон отдельный большой разговор ниже.
Выбор русского языка
По умолчанию интерфейс английский. Русский доустанавливается пакетом языков YetiForceCRMLanguages: его подкладывают в каталог с языками, после чего русский появляется в списке доступных в настройках системы и в профиле пользователя. Я обычно ставлю русский языком по умолчанию для всей системы и отдельно проверяю, что форматы даты и чисел встали корректно. Учтите: часть служебных наименований и технических подсказок может оставаться на английском — это нормально для локализации сообщества.
Конфиг nginx и TLS: боевой server-блок
Связка YetiForce nginx php-fpm требует аккуратного server-блока. Корень сайта должен указывать не на весь каталог CRM, а на подкаталог public_html — именно там лежит точка входа. Всё остальное (config, storage, приватные модули) наружу отдавать нельзя. Вот фрагмент рабочего конфига, который я использую:
server {
listen 80;
server_name crm.example.ru;
root /var/www/yetiforce/public_html;
index index.php;
client_max_body_size 100M;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_read_timeout 600;
}
# закрываем служебные каталоги
location ~ ^/(config|cache|storage|app_data|user_privileges)/ {
deny all;
return 403;
}
location ~ /\.(ht|git) { deny all; }
}
Обратите внимание на три вещи. Во-первых, client_max_body_size 100M — он должен совпадать с post_max_size и upload_max_filesize в php.ini, иначе nginx обрежет вложение раньше, чем до него доберётся PHP, и пользователь получит непонятную ошибку. Во-вторых, fastcgi_read_timeout 600 согласован с max_execution_time — иначе длинные отчёты будут обрываться по таймауту веб-сервера. В-третьих, блок deny для служебных каталогов — это не паранойя, а базовая гигиена: в config лежат реквизиты базы.
После проверки nginx -t и systemctl reload nginx ставим бесплатный сертификат Let's Encrypt через плагин certbot для nginx — он сам пропишет редирект и параметры TLS:
sudo certbot --nginx -d crm.example.ru --redirect --agree-tos -m admin@example.ru
Грабля с certbot: режим standalone поднимает собственный веб-сервер на 80 порту и конфликтует с уже работающим nginx — вы получите ошибку «address already in use». Для системы, которая уже отдаётся через nginx, всегда используйте плагин --nginx, а не standalone. Standalone уместен только когда веб-сервер выключен, например при первичном выпуске до настройки хоста.
Cron — то, без чего YetiForce наполовину мёртв
Если бы меня попросили назвать единственную самую частую причину обращений «купили, поставили, а оно не работает как надо» — это забытый или неправильно настроенный крон. YetiForce cron настройка — это не опция, а обязательный элемент архитектуры. Вся фоновая механика системы живёт в файле cron.php, который должен запускаться раз в минуту от имени веб-пользователя.
Что именно ломается без крона: не выполняются workflow (автоматические сценарии по сделкам и задачам), не работает почтовый сканер (входящие письма не превращаются в записи CRM), не рассылаются уведомления, не обновляются связанные данные и напоминания. Внешне система выглядит живой — карточки открываются, записи сохраняются, — но вся автоматизация стоит. И это тот случай, когда «поставили и забыли — письма не ходят» бьёт по клиенту через неделю, когда менеджеры уже завели в системе реальные сделки.
Настраивается крон одной строкой в crontab пользователя www-data:
sudo crontab -u www-data -e
# добавить строку — запуск планировщика раз в минуту:
* * * * * cd /var/www/yetiforce && /usr/bin/php8.3 cron.php >/dev/null 2>&1
Здесь важны две детали. Первая: крон вешаем именно на www-data, а не на root — иначе cron.php создаст временные файлы с неверным владельцем, и потом веб-процесс не сможет их перезаписать. Вторая: путь к php должен быть к бинарю CLI (php8.3), и рабочий каталог — корень CRM.
После настройки обязательно проверяю статус планировщика в панели администратора: там есть раздел, где видно время последнего запуска каждой служебной задачи. Если время «застыло» или показывает многочасовую давность — крон не работает, и это надо чинить до того, как система уйдёт в продуктив. Я всегда делаю эту проверку финальным пунктом приёмки: захожу в администраторскую панель и убеждаюсь, что все фоновые процессы отработали в пределах минуты назад.
Совет: первое время логируйте вывод крона в файл, а не в /dev/null. Замените хвост строки на >>/var/log/yetiforce-cron.log 2>&1 на пару дней после запуска — так вы сразу увидите ошибки почтового сканера или workflow, если что-то настроено криво. Когда убедились, что всё чисто, можно вернуть /dev/null.
Первые 60 минут после логина: чек-лист первичной настройки
Система установлена, крон тикает, TLS выпущен. Но отдавать это клиенту рано. Есть короткий ритуал первого часа, который я прохожу на каждом внедрении — он закрывает базовую безопасность и снимает половину будущих вопросов. Вот мой чек-лист по порядку:
- Сменить пароль администратора и включить 2FA. Учётка, заведённая при установке, — первая цель для перебора. Ставлю длинный пароль и сразу включаю двухфакторную аутентификацию для админа через приложение-аутентификатор. Это две минуты, которые экономят нервы.
- Прописать домен и системный e-mail. В настройках указываю рабочий адрес CRM и почтовый ящик, от которого система шлёт уведомления. Без корректного домена ломаются ссылки в письмах.
- Часовой пояс и валюта. Выставляю Europe/Moscow и рубль как основную валюту. Если этого не сделать сразу, потом придётся пересчитывать суммы в сделках.
- Роли и профили прав. Проектирую иерархию: кто видит все сделки, кто только свои, у кого есть доступ к настройкам. YetiForce гибок в правах — этим надо пользоваться сразу, а не раздавать всем администраторский доступ «пока разберёмся».
- Отключить лишние модули. Из коробки система несёт десятки модулей. Оставляю то, чем клиент реально будет пользоваться, остальное скрываю — это упрощает интерфейс и снижает путаницу у менеджеров.
- Проверить «Состояние системы». В администраторской панели есть сводка о состоянии: крон, права, обновления, безопасность. Прохожу по ней и убеждаюсь, что все индикаторы зелёные.
Отдельно скажу про почту. Настройка почтового ящика для сканера и исходящих уведомлений — это то, ради чего мы ставили php-imap. Проверяю, что тестовое письмо уходит, а входящее корректно подтягивается сканером (тем самым, который живёт на кроне). Только после этого система готова к передаче пользователям.
Docker-вариант: когда контейнер уместен, а когда нет
Меня регулярно спрашивают про YetiForce docker — мол, зачем возиться с nginx, php-fpm и MariaDB руками, если есть официальный образ. Отвечу честно, как практик: у контейнера есть своя ниша, но это не боевая система на 50 рабочих мест.
Официальный Docker-образ отлично подходит, чтобы за десять минут поднять систему для теста, демо клиенту или пилота на небольшой группе. Вы получаете готовую сборку без ручной настройки лимитов и расширений — удобно, чтобы показать интерфейс и договориться о процессах. Вот минимальный compose-пример для такого пилота:
# docker-compose.yml — для пилота/демо, НЕ для боя на 50 РМ
services:
db:
image: mariadb:10.11
environment:
MYSQL_ROOT_PASSWORD: changeme
MYSQL_DATABASE: yetiforce
command: --max-allowed-packet=128M --sql-mode="NO_ENGINE_SUBSTITUTION"
volumes:
- db_data:/var/lib/mysql
app:
image: yetiforce/yetiforce:latest
ports:
- "8080:80"
depends_on:
- db
volumes:
- app_data:/var/www/html
volumes:
db_data:
app_data:
А теперь почему в проде я всё равно ставлю классикой. Во-первых, тонкая настройка php-fpm-пула, крона от www-data и буферного пула MariaDB под конкретную нагрузку прозрачнее и предсказуемее на «голой» ВМ. Во-вторых, бэкапы: снять дамп базы и архив storage с обычной машины и проверить восстановление проще, чем городить логику вокруг именованных томов. В-третьих, обновления и разбор инцидентов — когда что-то идёт не так на боевой системе с живыми сделками, я хочу иметь прямой доступ к логам и файлам без прослойки контейнера.
Итог простой: Docker — для теста и пилота, классическая установка на выделенной ВМ — для продуктива. Именно так мы и работаем на внедрениях.
Сколько это стоит и когда звать подрядчика
Разделю два разных вопроса, которые клиенты часто путают. Голая установка YetiForce — это работа на вечер. Опытный инженер разворачивает стек, проходит валидатор, настраивает nginx, TLS и крон за несколько часов. Если вам нужна именно техническая инсталляция и вы готовы дальше сами разбираться с процессами — это несложно, и весь этот гайд для того и написан.
Но продуктивная CRM — это не установленный движок. Это установка плюс продуманные права, плюс настроенные под ваши процессы воронки и автоматизация, плюс интеграции с почтой и телефонией, плюс обучение менеджеров и приёмка. Такой проект занимает не вечер, а 2-4 недели календарно — с учётом согласований, переноса данных и адаптации людей. И вот здесь честно стоит звать подрядчика, потому что провал большинства внедрений CRM — это не про технику, а про то, что систему настроили «как из коробки» и не научили ей пользоваться.
По деньгам логика такая. Само ПО бесплатно — это ключевое преимущество self-hosted CRM установки перед облачными подписками. Вы платите один раз за внедрение и дальше за сопровождение и хостинг, а не отдаёте ежемесячную плату за каждого пользователя годами. Давайте прикинем на горизонте пары лет:
- Облачная CRM по подписке: платите за каждое рабочее место каждый месяц. На 30 пользователях за два года набегает сумма, на которую можно несколько раз внедрить и сопровождать своё решение. И данные лежат не у вас.
- YetiForce self-hosted: разовый бюджет внедрения плюс аренда ВМ и сопровождение. На дистанции в 2-3 года выходит заметно дешевле, а данные — в вашем контуре, на ваших серверах.
Когда точно стоит отдать задачу на аутсорс, а не тянуть силами штатного «который в компьютерах разбирается»: если у вас больше 15-20 пользователей, если нужна интеграция с 1С или телефонией, если критична непрерывность работы и бэкапы, и если некому потом сопровождать систему. Мы в ITfresh как раз закрываем весь цикл — от установки до эксплуатации — и берём на себя ответственность за то, чтобы система работала, а не просто была установлена.
Ориентир по решению: если задача разовая и у вас есть кому поддерживать — ставьте сами по этому гайду. Если CRM становится рабочим инструментом отдела продаж и от неё зависит выручка — считайте не стоимость установки, а стоимость простоя и потерянных лидов. Обычно после этого подсчёта вопрос «звать ли подрядчика» отпадает сам собой.

Оставить комментарий