Если что-то не работает
Как запускать скрипт по расписанию без cron на сервере
Коротко
Запустить скрипт по расписанию без cron можно, сделав расписание частью самого приложения: скрипт работает постоянно и сам решает, когда сработать — бесконечным циклом с паузой, если точное время не важно, или библиотекой расписания (schedule и APScheduler в Python, node-cron в Node.js), если нужно конкретное время суток. Отдельной настройки расписания в кабинете Netrun нет, поэтому такой проект считается фоновым скриптом: он не засыпает, и на бесплатном тарифе ему дано 3 дня работы, а дальше нужен тариф Pro. Две вещи стоит предусмотреть сразу: записывать момент последнего успешного запуска в постоянную папку /data, потому что после перезапуска отсчёт начинается заново, и задавать часовой пояс в коде явно.
Обычно расписание — это cron на своём сервере: одна строка в crontab, и система сама запускает скрипт каждый час. Как только своего сервера нет, привычка ломается: терминала в кабинете облачной платформы нет, crontab открыть негде, и человек начинает искать вкладку «Расписание». В Netrun её тоже нет, и об этом честнее сказать сразу, чем дать вам искать её полчаса.
Рабочий способ другой, и он проще, чем кажется: расписание становится частью самого приложения. Скрипт не «запускается по будильнику снаружи», а живёт постоянно и сам решает, когда пора работать. Ниже — три варианта, как это сделать, два подводных камня, из-за которых расписание съезжает или срабатывает дважды, и одна тарифная деталь, о которой лучше знать заранее.
Сделайте паузу частью скрипта, если минуты не важны#
Самый простой вариант расписания — бесконечный цикл: скрипт делает работу, засыпает на нужное время и повторяет. Этого достаточно, когда важна частота, а не точное время: «примерно раз в час», «каждые десять минут», «раз в сутки». Учтите, что пауза отсчитывается от конца предыдущего запуска, а не от начала часа, поэтому момент срабатывания будет потихоньку уезжать, если сама работа занимает заметное время.
Возьмите библиотеку расписания, когда нужно конкретное время#
Если задача должна срабатывать «каждый день в 9 утра» или «по понедельникам», голого цикла с паузой мало — нужна библиотека расписания. В Python для простых правил берут schedule, а когда правил много или привычнее cron-подобная запись — APScheduler; в Node.js ту же роль играет node-cron. Скрипт при этом всё равно должен работать постоянно: библиотека — это будильник внутри вашего приложения, а не внешняя служба, которая поднимет его сама.
Разбудите сайт по ссылке, если он у вас уже есть#
Когда сайт или API у вас уже опубликован, расписание можно вынести наружу: добавьте отдельный адрес вроде /tasks/hourly, который делает нужную работу, а внешний сервис-будильник пусть открывает его по расписанию. Адрес публичный, поэтому закройте его секретным ключом в параметре или заголовке, а сам ключ читайте из переменной окружения. Работу держите короткой и отвечайте сразу: долгий ответ рискует оборваться по таймауту на стороне того, кто дёргает ссылку. Плюс варианта в том, что сайт на бесплатном тарифе живёт бесконечно: он засыпает при простое и просыпается, когда будильник открывает ссылку.
Задайте часовой пояс явно#
Часовой пояс на сервере почти наверняка не совпадает с вашим, поэтому «в 9 утра» легко превращается в другое время суток. Не полагайтесь на местное время машины: указывайте пояс явно — в Python это ZoneInfo и параметр часового пояса у планировщика, в Node.js аналогичная настройка у библиотеки. Если сомневаетесь, выведите в лог текущее время при старте: сразу станет видно, по какому поясу считает ваш скрипт.
Запишите момент последнего запуска в постоянную папку /data#
После перезапуска — вы обновили код или проект подняли после сбоя — отсчёт начинается заново, и библиотека расписания не помнит, что уже успела сделать. Поэтому записывайте момент последнего успешного запуска в файл в папке /data: она переживает и обновление кода, и перезапуск, а посмотреть её содержимое можно на вкладке «Данные». При старте прочитайте эту отметку и решите сами: работа за сегодня сделана — пропустить, пропущена — выполнить сразу. У проектов со своим docker-compose папки /data нет, там ту же отметку кладут в именованный том или в базу.
Загрузите код и проверьте первое срабатывание по логам#
Загрузите папку ZIP-архивом или импортируйте репозиторий с GitHub, в том числе приватный — платформа сама определит язык, поставит зависимости и запустит скрипт. Дальше откройте логи в кабинете: там видно и старт, и каждое срабатывание, если вы пишете о нём строку в лог. Для первой проверки удобно временно поставить короткий интервал, убедиться, что задача действительно выполняется, и только потом вернуть настоящее расписание.
Итог короткий: планировщика как отдельной настройки в кабинете нет, искать его не нужно — расписание живёт внутри вашего скрипта. Отсюда следует и тарифная сторона: постоянно работающий скрипт не засыпает, будить его некому, поэтому на бесплатном тарифе такому проекту дано три дня работы, а потом он выключается. Код, настройки и секреты при этом остаются на месте, и за сутки до выключения приходит предупреждение. Если задача должна срабатывать неделями и месяцами, нужен тариф Pro — актуальные цены и лимиты видны в кабинете. Попробовать Netrun.
Частые вопросы
Как запускать python-скрипт каждый час?
Оберните полезную работу в бесконечный цикл с паузой на час — этого хватает, когда важна частота, а не точная минута. Если запуск должен приходиться на начало часа, возьмите библиотеку расписания: schedule для простых правил или APScheduler, когда правил много. В обоих случаях скрипт работает постоянно, а публикуется он как обычный фоновый проект — отдельного расписания в кабинете задавать не нужно.
Что будет с расписанием, если проект перезапустится?
Отсчёт начнётся заново: и цикл с паузой, и библиотека расписания считают время от старта процесса и не помнят прошлых срабатываний. Из-за этого задача может выполниться второй раз подряд или пропустить свой момент, если перезапуск пришёлся ровно на него. Лечится отметкой: записывайте время последнего успешного запуска в файл в постоянной папке /data и сверяйтесь с ней при старте.
Почему задача сработала не в то время, которое указано в коде?
Чаще всего дело в часовом поясе: время на сервере не обязано совпадать с вашим, и «9 утра» считается по поясу машины, а не по вашему городу. Задайте пояс явно — в Python через ZoneInfo и параметр планировщика, в Node.js через настройку библиотеки. Вторая по частоте причина — цикл с паузой: он отсчитывает интервал от конца прошлой работы, поэтому время срабатывания постепенно смещается.
schedule или APScheduler — что выбрать?
Для одного-двух простых правил вроде «каждый час» или «каждый день в 9:00» удобнее schedule: он читается почти как обычное предложение и не требует настройки. APScheduler берут, когда правил много, нужна cron-подобная запись или задачи должны выполняться параллельно. В Node.js обе роли обычно закрывает node-cron.
Можно ли запускать задачу раз в неделю или раз в месяц?
Да, редкие расписания библиотеки поддерживают так же, как ежечасные. Но чем реже задача, тем важнее отметка о последнем запуске: между двумя срабатываниями проект успеет пережить обновление кода или перезапуск, и без отметки очередной месяц может пройти впустую. Храните дату последнего запуска в постоянной папке /data и при старте проверяйте, не пора ли выполнить пропущенное.
Как узнать, что задача действительно отработала?
Пишите в лог по строке на каждое срабатывание — с временем и результатом. Логи видны в кабинете в реальном времени, поэтому и успешный запуск, и ошибку видно сразу. Если скрипт упадёт целиком, проект перезапустится, а вам придёт уведомление, так что молчаливой поломки не будет.
Есть ли запуск по расписанию?
Отдельной настройки расписания в кабинете нет. Расписание делают частью самого приложения: скрипт работает постоянно и сам решает, когда сработать — циклом с паузой или библиотекой расписания. Такой проект считается фоновым скриптом: он не засыпает, поэтому на бесплатном тарифе работает 3 дня, а для постоянной работы нужен тариф Pro.
Засыпают ли боты и фоновые скрипты?
Нет, засыпают только сайты: сайт просыпается сам, когда его открывают. Бота и фоновый скрипт разбудить нечем — к ним никто не приходит по ссылке, они работают сами по себе. Поэтому на бесплатном тарифе они работают 3 дня, а дальше, чтобы бот работал круглосуточно, нужен тариф Pro.
Сохранятся ли данные при обновлении кода?
Да, если данные лежат в постоянном хранилище. У обычного проекта это папка /data: всё, что приложение туда сохранило, остаётся при обновлении кода и перезапуске, а посмотреть и скачать файлы можно на вкладке «Данные». Если вы описали сервисы сами в docker-compose, постоянное хранилище — это именованные тома из вашего файла, и папки /data у такого проекта нет. Файлы, записанные мимо хранилища, при следующей публикации создаются заново. Ссылка проекта в любом случае остаётся прежней.