Автоматизация рутинных задач на сайте почти всегда упирается в cron: чистка кэша, рассылка писем, генерация отчетов, резервные копии, импорт данных из внешних систем. На собственном сервере все относительно прозрачно, но на виртуальном хостинге есть ограничения и нюансы, которые легко превратить в часы отладки и переписку с техподдержкой.
Разберем, как именно устроен cron на виртуальном хостинге, чем он отличается от классического системного cron, как правильно запускать PHP-скрипты и cron.php у популярных CMS, где искать логи и как диагностировать проблемы, не имея root-доступа.
Что такое cron и чем он отличается на виртуальном хостинге
Классический cron в Linux — это демон, который читает конфигурации из /etc/crontab, /etc/cron.d и пользовательских файлов crontab, и запускает указанные команды по расписанию. На выделенных серверах и VDS вы можете редактировать системные конфиги, создавать отдельные файлы в /etc/cron.d, использовать systemd timers вместо cron и так далее. Подробно про различия между cron и таймерами systemd я писал в статье про автоматизацию задач через systemd timers.
На виртуальном хостинге ситуация другая: у вас нет root-доступа и, как правило, нет возможности трогать системный cron. Провайдер дает поверх этого удобный пользовательский интерфейс для настройки заданий.
Cron на виртуальном хостинге почти всегда обернут панелью управления. Ваши задания в итоге попадают в системный cron под нужным пользователем, но вы работаете только через web-интерфейс или ограниченный crontab.
Типовая схема выглядит так:
- В панели хостинга вы создаете задание cron (команда, расписание, email для отчетов).
- Панель генерирует нужную запись в системном cron сервера.
- Системный cron запускает команду от имени вашего Unix-пользователя.
- Вы видите результат в логах cron, почтовой сводке или в логах приложения.
Отсюда вытекают ключевые отличия и ограничения:
- Нельзя трогать системные файлы
/etc/crontab,/etc/cron.d. - Частота выполнения обычно ограничена (например, не чаще одного раза в минуту, иногда — раз в 5–15 минут).
- Есть лимиты по времени выполнения и ресурсам (CPU, память), которые совпадают или близки к лимитам PHP для CLI/CGI.
- Иногда нельзя напрямую вызывать бинарники из нестандартных директорий — только через полный путь.
Формат расписания cron на хостинге
Формат расписания в cron универсален: пять полей (иногда шесть, если отдельно указывают год), разделенные пробелами. Классическая форма:
минуты часы день_месяца месяц день_недели команда
Примеры:
*/5 * * * *— каждые 5 минут.0 * * * *— каждый час, в ноль минут.0 3 * * *— каждый день в 03:00.0 3 * * 1— по понедельникам в 03:00.30 2 1 * *— в 02:30 первого числа каждого месяца.
На некоторых панелях виртуального хостинга вместо «сырых» выражений cron есть выпадающие списки: «каждый час», «каждый день в X:YY» и так далее. Но под капотом это все равно те же пять полей cron, просто собранные за вас.
Частые ошибки с расписанием:
- Путают день месяца и день недели (четвертое и пятое поля).
- Используют запятую и дефис, не разобравшись:
1-5— диапазон,1,5— только два значения. - Пишут
* /5вместо*/5и получают ошибку парсинга. - Ожидают «раз в 2 часа» от
0 */2 * * *, но забывают, что сервер живет в другом часовом поясе, и путаются во времени.
Если панель хостинга позволяет, имеет смысл тестировать выражение cron на тестовой команде вроде date и логировать вывод в файл, чтобы убедиться, что оно срабатывает в нужные моменты. На собственном сервере для более сложных расписаний можно подключать systemd timers, но в рамках общего виртуального хостинга почти всегда приходится укладываться в классический формат cron.

Как запускать PHP-скрипты через cron на виртуальном хостинге
Самый частый сценарий: надо периодически запускать PHP-скрипт, который лежит в каталоге сайта. Например, artisan schedule:run в Laravel, bin/console в Symfony или пользовательский cron.php для своего кода.
Есть два базовых подхода:
- Вызывать CLI-интерпретатор PHP и передавать ему путь к скрипту.
- Дергать HTTP-URL (например,
example.com/cron.php) утилитойwgetилиcurl.
На виртуальном хостинге почти всегда рекомендуется первый вариант (CLI), если он доступен:
/usr/bin/php -d memory_limit=512M /home/user/example.com/artisan schedule:run
Нюансы:
- Нужно знать реальный путь к PHP CLI. Часто это
/usr/bin/phpили что-то вроде/usr/local/bin/php. На многих хостингах путь указан в документации или в панели. - Путь к скрипту должен быть абсолютным, от корня файловой системы:
/home/user/example.com/..., а не./artisanилиartisan. - Иногда нужно подставить нужную версию PHP (например,
/usr/bin/php81), особенно если сайт работает на PHP 8.1, а по умолчанию в системе стоит 7.4.
Почему запуск через HTTP хуже:
- Зависимость от работы веб-сервера и правил в
.htaccessили конфиге виртуального хоста. - Ограничения по времени выполнения и памяти, как для обычного веб-запроса.
- Дополнительный overhead на HTTP, TLS, маршрутизацию, возможные редиректы.
- Риск, что URL cron-а случайно станет доступен извне, если не защитить его ключом, IP-фильтром или Basic-авторизацией.
Но иногда HTTP — это единственно доступный способ (например, нет доступа к CLI PHP или к cron на уровне пользователя, а панель умеет только «URL cron»). В этом случае хотя бы:
- Защищайте cron-URL секретным ключом в query string (и проверкой этого ключа в скрипте).
- Ограничивайте доступ по IP, если это возможно.
- Логируйте каждый запуск cron-скрипта, чтобы понимать, что он реально отрабатывает.
Как правильно задать команду cron на виртуальном хостинге
Чтобы задача стабильно работала, в команду нужно «упаковать» несколько вещей: вызов интерпретатора, сам скрипт и, часто, перенаправление вывода в лог.
Базовый шаблон для PHP:
/usr/bin/php /home/user/example.com/public/cron.php >> /home/user/logs/cron.log 2>&1
Что здесь происходит:
/usr/bin/php— бинарник PHP CLI./home/user/example.com/public/cron.php— путь к вашему скрипту.>> /home/user/logs/cron.log— добавляем стандартный вывод (stdout) к файлу лога.2>&1— перенаправляем стандартный поток ошибок (stderr) туда же, в лог.
Несколько рекомендаций:
- Не полагайтесь на переменные окружения
PATH— указывайте полные пути. - Создайте отдельную директорию для логов cron, чтобы не захламлять логи сайта.
- Чистите логи cron — или через отдельное cron-задание, или logrotate (если доступен), или вручную.
Если нужно выполнить команду из конкретного каталога (например, где лежит artisan), можно использовать конструкцию с cd:
cd /home/user/example.com && /usr/bin/php artisan schedule:run >> /home/user/logs/cron-artisan.log 2>&1
В этом случае Laravel увидит правильный рабочий каталог, а относительные пути будут работать так же, как при ручном запуске из SSH.
Частые задачи cron на виртуальном хостинге и типовые команды
Рассмотрим несколько типовых сценариев, которые чаще всего встречаются у вебмастеров и разработчиков.
1. Очистка временных файлов и кэша
Если CMS или фреймворк складывает временные файлы в определенную директорию, логично периодически чистить старые файлы, чтобы не забить квоту диска.
Пример задачи:
0 4 * * * find /home/user/example.com/storage/tmp -type f -mtime +7 -delete
Такое задание каждый день в 04:00 удаляет файлы старше 7 дней. Перед боевым включением имеет смысл сначала запустить ту же команду без -delete и с -print, посмотрев, что именно будет удаляться.
2. Запуск планировщика задач Laravel
Рекомендуемая схема для Laravel — один cron, который каждую минуту дергает artisan schedule:run, а уже внутри приложения описано, что запускать и когда:
* * * * * cd /home/user/example.com && /usr/bin/php artisan schedule:run >> /home/user/logs/laravel-schedule.log 2>&1
На виртуальном хостинге нужно только убедиться, что:
- PHP CLI той же версии, что и PHP в вебе.
- Ограничения по времени выполнения в
php.iniдля CLI не слишком жесткие (или их можно переопределить в командной строке через-d).
3. Cron для WordPress wp-cron.php
По умолчанию WordPress дергает wp-cron.php на каждом запросе к сайту, что неэффективно под нагрузкой. На виртуальном хостинге можно отключить внутренний псевдо-cron и настроить системный.
Шаги:
- В
wp-config.phpдобавить:
define('DISABLE_WP_CRON', true);
- В cron в панели хостинга создать задачу, которая раз в несколько минут дергает
wp-crон.phpчерез PHP CLI:
*/5 * * * * /usr/bin/php /home/user/example.com/public/wp-cron.php >> /home/user/logs/wp-cron.log 2>&1
Либо, если CLI недоступен, через HTTP (в примере домен условный):
*/5 * * * * wget -q -O - example.com/wp-cron.php?doing_wp_cron=1 >/dev/null 2>&1
Но HTTP-вариант лучше закрыть хотя бы ограничением по User-Agent или IP на уровне веб-сервера, чтобы скрипт нельзя было дергать извне.
4. Резервное копирование файлов и базы
На виртуальном хостинге часто нужно хотя бы раз в ночь создавать дамп базы и архив файлов сайта. Простейший пример:
0 3 * * * mysqldump -u dbuser -p'secret' dbname | gzip > /home/user/backups/db-$(date +%F).sql.gz
Тут нужно учитывать ограничения:
- Время выполнения cron-заданий — если база большая, дамп может не влезть в лимит.
- Дисковая квота — архивы быстро занимают место, обязательно продумывайте ротацию.
- Хранить пароли в cron-команде небезопасно; лучше, если панель поддерживает специальные «подстановки» или переменные, либо использовать конфигурационный файл MySQL клиента (
~/.my.cnf), если разрешено.
Если вы делаете бэкапы не только локально, но и в объектное хранилище, посмотрите статью по удаленным резервным копиям сайтов и баз данных с помощью restic и Borg: о бэкапах в S3-совместимое хранилище.

Где смотреть логи cron на виртуальном хостинге
На полноценном сервере есть системные логи cron (/var/log/cron, /var/log/syslog и т.д.), но на виртуальном хостинге прямой доступ к ним чаще всего закрыт. Поэтому важно сразу заложить логирование в саму команду cron (через перенаправление stdout и stderr).
Если вы настроили:
/usr/bin/php /home/user/example.com/cron.php >> /home/user/logs/cron.log 2>&1
то:
- Любой
echo,printв скрипте окажется вcron.log. - Ошибки PHP (warnings, notices, fatals), выводимые в stderr, тоже попадут в лог.
- При необходимости вы можете временно добавить отладочный вывод (time stamps, debug messages), чтобы понять, доходит ли выполнение до нужного участка кода.
Дополнительно у некоторых хостеров есть:
- Специальные «логи cron» в панели управления, где показывают только факт запуска/ошибку, без самого вывода.
- Отправка результатов выполнения задания на email (по аналогии с классическим cron-демоном).
Полезный прием: временно упростить команду cron до чего-то заведомо работающего, вроде:
/bin/date >> /home/user/logs/cron-test.log 2>&1
Если cron-test.log пополняется строками со временем — значит, cron работает, а проблема в вашей команде или в приложении. Если файл пуст — смотрите расписание, ограничения панели или обращайтесь в поддержку.
Частые проблемы и как их диагностировать
На практике задачи cron на виртуальном хостинге чаще «не работают», чем работают с первого раза. Разберем типичные грабли.
1. Команда не выполняется из-за относительных путей
Когда вы тестируете скрипт из SSH с помощью:
php cron.php
он выполняется в текущем каталоге, где вы находитесь. В cron же рабочий каталог по умолчанию другой (обычно домашняя директория пользователя или корень файловой системы), и относительные пути ломаются.
Решения:
- Использовать абсолютные пути везде, где это возможно.
- Или в самом начале задания cron сделать
cdв нужный каталог (как в примерах выше).
2. Использование неправильной версии PHP
Сайт работает на PHP 8.1, а cron запускается через /usr/bin/php, который оказывается PHP 7.4. В результате — ошибки несовместимости, странные падения только в cron.
Проверьте версии:
/usr/bin/php -v
/usr/local/bin/php -v
И используйте в cron именно тот путь, который соответствует версии, назначенной для вашего виртуального хостинга. Иногда панель прямо подсказывает правильную команду для cron.
3. Ограничения по времени и памяти
На виртуальном хостинге нет бесконечных ресурсов. Если cron-скрипт делает тяжелую работу (массовые рассылки писем, импорт больших CSV, перерасчет статистики), он легко упирается в:
max_execution_timeдля PHP CLI;memory_limit;- лимиты CPU/IO аккаунта, которые провайдер навешивает для защиты от «шумных соседей».
Симптомы: скрипт обрывается посередине, часть задач не доделана, в логах — неполные отчеты или ошибки «Allowed memory size exhausted».
Что можно сделать:
- Разбить тяжелую работу на более мелкие шаги (batch processing).
- Увеличить лимиты через
-dв командной строке, если это разрешено:
/usr/bin/php -d memory_limit=512M -d max_execution_time=0 /home/user/example.com/cron.php
- Оптимизировать сам код (делать меньше запросов к базе за один запуск, использовать очереди и т.д.).
4. Задание вообще не запускается
Иногда панель хостинга показывает задание, но оно фактически не попадает в системный cron (ошибка панели, лимит по числу задач, блокировка аккаунта).
Алгоритм отладки:
- Сделать максимально простое задание (как
/bin/date >> cron-test.log). - Убедиться, что через 1–2 цикла лог появился и обновляется.
- Если нет — перепроверить расписание, статус задания в панели (не выключено ли оно), наличие ошибок в интерфейсе.
- Если все выглядит нормально, а задание не срабатывает — писать в поддержку и просить проверить системный cron по вашему аккаунту.
5. Путаница с часовыми поясами
Сервер хостинга может жить в UTC, ваш проект — в Европе или Азии, а вы сами — еще в одном поясе. В итоге «запуск в 03:00» по cron и «03:00» в приложении — это две разные вещи.
Рекомендации:
- Уточните часовой пояс сервера (часто видно в панели или можно спросить у поддержки).
- При необходимости учитывайте смещение в расписании cron.
- В логах cron явно записывайте время с указанием зоны или хотя бы
date -R, чтобы уменьшить путаницу.
Безопасность cron на виртуальном хостинге
Хотя cron — это всего лишь планировщик, он запускает команды от имени вашего пользователя, и через него можно как защитить проект (регулярные бэкапы, чистка логов), так и случайно навредить (стереть важные файлы).
Несколько практических правил:
- Никогда не запускайте через cron «сильные» команды вроде
rm -rfбез очень точных условий и предварительного тестирования. - По возможности, оборачивайте опасные действия в проверенный PHP/CLI-скрипт, а в cron выносите только вызов этого скрипта.
- Ограничивайте доступ к cron-URL, если все-таки используете HTTP-вариант.
- Старайтесь не хранить пароли и ключи прямо в строках cron; лучше — в конфигурациях приложений или в файлах настроек, которые не лежат в web-доступном каталоге.
Организация и документация cron-задач
На любом более-менее живом проекте через полгода уже никто не помнит, кто и зачем настроил то или иное задание cron, почему оно запускается именно так и с такой частотой. Чтобы не превратить cron в «черный ящик», полезно соблюдать пару дисциплинарных правил.
Рекомендации по организации:
- Вести отдельный файл-документацию (например, в репозитории проекта), где перечислены все cron-задачи: расписание, команда, назначение, ответственный.
- По возможности, хранить важные скрипты и cron-команды в кодовой базе (например, отдельным shell-скриптом, который затем вызывается из панели).
- При деплое на другой хостинг иметь чек-лист: какие cron-задания нужно перенести, с каким расписанием.
Хорошая практика — выносить «логическую» задачу в приложение (Laravel scheduler, Symfony Messenger, собственный планировщик), а системный cron использовать только как триггер, который раз в минуту запускает этот внутренний планировщик. Тогда вы переносите cron между окружениями проще, а всю логику расписания контролируете в коде, а не в панели хостинга. Если в перспективе планируете переезд на VDS, заранее продуманная схема cron заметно упростит миграцию.
Итоги
На виртуальном хостинге cron — не такой гибкий, как на собственном сервере, но для большинства сайтов и задач его возможностей более чем достаточно. Главное — учитывать ограничения провайдера, использовать PHP CLI, а не HTTP там, где это возможно, и сразу закладывать логирование и диагностику.
Кратко по ключевым моментам:
- Используйте правильный путь к PHP и абсолютные пути к скриптам.
- Всегда логируйте stdout и stderr в отдельные файлы.
- Проверяйте расписание cron-выражений и часовой пояс сервера.
- Разбивайте тяжелые задачи, учитывайте лимиты по времени и памяти.
- Документируйте все cron-задания проекта, чтобы через полгода самому себя понимать.
С таким подходом cron на виртуальном хостинге перестает быть источником сюрпризов и превращается в надежный инструмент автоматизации для ваших проектов.


