Запускаем Python-скрипт с помощью Cron на Linux
Я, как настоящий старовер, решил построить «data-pipeline» без коннекторов и DAG-менеджеров. Положив два перста на мышку, началась упорная работа. Разобрался с API рекламных систем, установил драйвер bigquery, залил первую таблицу в датасет. Победа была близка, осталось всё автоматизировать. Я начал разворачивать Airflow, а потом проснулся и вспомнил про cron.
Вспомнив про ранее купленный на лучшемгосподихостинге бегете VPS, куда я деплоил свой tf-idf кластеризатор. Было решено залить скрипт на сервер и настроить его запуск на 6 утра ежедневно.
Cron — это демон, а демон — это программа работающая в фоновом режиме. Ну а если вы программировали на Python — вам должны быть знакомы процессы-демоны. Запуск Cron-задания — это легко, но только в случаях когда мы говорим об выполнении php и bash скриптов. С Python всё иначе.
Устанавливаем Python на сервер
Выполняем, указные команды на примере Ubuntu.
sudo apt update
sudo apt install python3.8
sudo apt install -y python3-pip
Проверяем успешность установки командой python3.
Создаем виртуальное окружение virtalenv
Следующий шаг — изолировать наш проект в отдельное виртуальное окружение, куда мы будем устанавливать нужные нам библиотеки.
pip3 install virtualenv # устанавливаем библиотеку cd /home/iakulshin # идем в папку вашего пользователя, тут на ваше усмотрение mkdir pipeline # создаем папку проекта cd /pipeline # переходим в папку virtualenv -p python3 venv # создаем виртуальное окружение, важно что мы устаналиваем с параметром -p, а то получим python 2.7 source venv/bin/activate # активируем
Теперь мы видим рядом в консоли перед строкой приписку (venv) — это значит, что мы в виртуальном окружении.
Запуск Python-скрипта с помощью Сron
Давай потестируем то, что у нас получилось на маленьком скрипте, который будет писать в файл дату и время его активации. Таким образом мы проверим как работает cron. Тестовый скрипт, который мы положим в корень папки проекта, у меня это /home/iakulshin/pipeline, заливаем через файловый менеджер filezilla и прочие, если вы хардкорный девопс-дата-инженер удачи вам с nano. Заливаем скрипт указанный ниже в нашу папку.
from datetime import datetime with open('test.txt', 'a+', encoding='utf-8') as file: file.write(datetime.today().strftime('%Y-%m-%d-%H-%M-%S') + '\n')
Давайте попробуем создать cron задание для тестового запуска. В целом нам будут нужны 2 команды:
crontab -l # выводит список текущих заданий crontab -e # открывает файл заданий crontab -r # удаляет файл задания Пишем в консоль crontab -e
Появлеятся файлик с крон задачами в редакторе nano. Наша задача установить задание, которое будет запускать наш скрипт каждую минуту.
* * * * * cd /home/iakulshin/pipeline && /home/iakulshin/pipeline/venv/bin/python3 test.py [минута] [час] [день] [месяц] [день недели] [Переходим в папку] [&& - означает "и"] [с помощью интерпретатора python3 запускаем файл test.py]
Делюсь лайфхаком — конструктор для составления расписаний cron
Наконец, в файлике test.txt каждую минуту появляется текущая дата, учения завершены, теперь рассмотрим возможные проблемы и способы их устранения.
Как понять что Cron срабатывает?
Чтобы удостовериться, что cron-таск отрабатывает, нам необходимо добавить задачу и обратиться к логам сервера, для этого идем в консоль и пишем следующую команду:
tail /var/log/syslog # получаем "хвост", последние 10 строк лог-файла
В нем вы увидите следующие записи:
Это означает, что cron срабатывает и воспроизводит команду, которую вы указали после звездочек. Но что делать, если python-скрипт всё еще не работает?
Cron срабатывает но Python-скрипт не выполняется
Самая типичная проблема, которая связана с «холостым» крон-таском — это недоступность библиотек, неверный выбор virtual env и версии python. Способ выбранный выше — это способ к которому я пришел спустя десяток часов поисков и изучения stackoverflow. Что нужно проверить для успешного запуска скрипта:
Возьмите команду, которую собирались добавь в крон и запустите её, это поможет словить ошибки связанные с недоступностью библиотек. В моем случае Скрипт не видел импортируемый файл, это я вылечил добавлением папки в системный путь. Добавляем в скрипты следующий код:
#!/home/iakulshin/bq_uploader/venv/bin/python import sys sys.path.insert(1, '/home/iakulshin/bq_uploader/') # Путь до вашей папки со скриптом
Если скрипт запускается по прямой команде из консоли, но cron всё еще не выполняется, то ошибка 100% в том, что ваш скрипт запускается не из под virtualenv или вы запускаете скрипт из под python не подходящей версии, поэтому проверяем следующее:
- Мы перешли в папку со скриптом командой cd
- Мы обратились к интерпретатору python3 находящемуся в папке с виртуальным окружением нашего проекта.
В целом данный гайд должен помочь вам разобраться с запуском Python скриптов с помощью Cron. Однако, я оставлю ссылки на полезные треды в stackoverflow, где представлены дополнительные способы решения этой проблемы.
Запуск Python-скрипта с Cron через Bash-скрипт: https://stackoverflow.com/questions/12534135/crontab-not-executing-a-python-script