Введение

У меня была задача «Собирать статистику постов в vk каждый час». Я не являюсь разработчиком или DevOps специалистом. Поэтому мой способ решения задачи сложился из поисковых запросов, личного опыта, советов друзей и коллег.

Решение я разбил на 2 части:

  1. Написать код для сбора. (см. статью https://habr.com/ru/post/720862/)

  2. Запустить процедуру на сервере с интервалом 1 час

В этой статье мы рассмотрим реализацию 2-го пункта. Если у вас нет 2 пункта подойдет любой другой код, которые требуется запускать по расписанию.

На схеме это будет выглядеть следующим образом.

Код на python публикуем на сервер через github, устанавливаем docker. В crontab задаем интервал для запуска docker контейнера
Код на python публикуем на сервер через github, устанавливаем docker. В crontab задаем интервал для запуска docker контейнера

Подготавливаем данные для Docker

Про Docker написано очень много статей, поэтому я не буду писать еще раз, что это и для чего используется. В контексте данной статьи Docker будет частью нашего решения. В следующем разделе будет ссылка на материал по теме Docker, который помог мне.

План действий:

  1. Создаем файл requrements.txt

  2. Настраиваем Dockerfile

  3. Настраиваем переменное окружение в коде python

  4. Оставляем словарь, который использует google sheet api*

* noted-point файл с расширением json, который используется в коде на python
* noted-point файл с расширением json, который используется в коде на python

requrements.txt  

В папке с вашим кодом создаем файл с точно таким же именем requrements.txt  Этим файлом мы говорим Docker, какие библиотеки нужно дополнительно установить и какой версии.

Как понять, что туда написать?

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

import os
import requests 
from pandas import json_normalize
import pandas as pd
from datetime import datetime
from datetime import *
import httplib2 
from oauth2client.service_account import ServiceAccountCredentials
import apiclient.discovery

В IDE в консоле пишем pip freeze.
Видим список всех установленных пакетов в вашем виртуальном окружение и их версии

Пример вывода списка библиотек с и их версии
Пример вывода списка библиотек с и их версии

Выбираем библиотеки, которые мы с вами используем в коде и переносим в requrements.txt

На выходе это будет выглядеть так:

Наполнение файла requrements.txt
Наполнение файла requrements.txt

Dockerfile

заполненная структура докер файла
заполненная структура докер файла

Создаем файл Dockerfile, без расширения. Открываем его и заносим данные

FROM python: «ваша версия python». Узнать ее можно набрав в терминале: python –V

Подробно останавливаться на всем не буду. Выше собранный requrements.txt будет использован в RUN.

ENV это переменное окружение, которые будут храниться внутри Docker. ENV TZ Europe/Moscow – установление московского времени.

Все остальные переменные необходимы для корректной работы кода. (см. статью https://habr.com/ru/post/720862/)

Конечно можно их и не прописывать и все оставить в коде. В моем случае, я решил, что оставлю все переменные в одном месте просто для своего удобства.

CMD указываем язык программирования и названия вашего файла с кодом в моем случае это vk_stat.py


Настраиваем переменное окружение в коде python

Мы удаляем значение переменных из кода, так как они у нас уже в Dockerfile.
Прописываем команду, которая будет забирать переменные окружения.

TOKEN_USER = os.getenv('TOKEN_USER')
VERSION = os.getenv('VERSION')
DOMAIN = os.getenv('DOMAIN')

Создаем сервер, публикуем код на GitHub

Я бы посоветовал прежде, чем перейти к этому шагу скачать отдельно docker desktop и провести тестирование на вашей локальной машине.

В этом видео вы найдете все что нужно по установки docker и кратко для чего он применяется. Мне данное видео очень помогло. https://www.youtube.com/watch?v=QF4ZF857m44

Для тех кто c Docker знаком предлагаю просмотреть фрагмент видео (ссылка выше) с 1:05:23 по 1:10:17

Добавлю лишь, если вы не хотите прописывать переменные внутри сервера, то сделайте закрытый репозиторий на GitHub!

Здесь не вижу смысла перечислять все шаги, если вы повторите за автором видео.

90% работы вами уже сделано. По итогам у вас:

- Создан сервер с опубликованном кодом через github + установленный docker

Отладка Cron

Далее через командную строку заходим на наш сервер.

Мне понравилась статья про cron здесь https://losst.pro/nastrojka-cron, но далее кратко напишу по сути. Набираем «crontab –e» в командной строке.

В самом конце набираем интервал для запуска контейнер. В моем случае каждый час. В помощь хороший сайт, который позволит сразу настроить интервал https://crontab.guru

Далее пишем команду Docker run –rm «имя вашего образа». Флажок –rm удаляет контейнер после его отработки. Не забываем сохранить наши изменения.

Cron перед сохранением. test - имя моего образа
Cron перед сохранением. test - имя моего образа

Проверить, не падает ли контейнер при запуске можно в логах. Введите команду grep CRON /var/log/syslog

Заключение

Данное решение позволяет выполнить поставленную задачу. Конечно его можно улучшить. Например, добавить логирование, написать класс и завернуть все в функции что позволит в будущем расширять функционал. Возможно радикально пересмотреть в целом предлагаемое мной решение.

Сервер обходиться в 200 рублей за месяц аренды. Работать код будет 4-6 месяцев. Если у кого-то есть решение, как можно сделать тоже самое без использования сервера, будет интересно почитать.

Код на GitHub

Комментарии (35)


  1. ky0
    00.00.0000 00:00
    +3

    "Негодующий комментарий про крон в 2023 году и systemd-таймеры"


    1. DmitriyB_33 Автор
      00.00.0000 00:00
      +1

      Благодарю. Подскажите, а чем крон плох? Я в статье обозначил, что не являюсь DevOps специалистом, нашел решение которое работает. Вполне может быть оно и не самое корректное. Статей много по настройки systemd-таймер , а пока разницы между ними плюсы/минусы не уловил.


      1. Areso
        00.00.0000 00:00

        systemd-таймеры это не про DevOps, а про владение Linux'ом.


      1. ky0
        00.00.0000 00:00
        +2

        Крон просто запускает скрипт. Таймер же оперирует сервисом, у которого есть собственные логи, состояние и понятные способы управления.


        Самый простой пример — что произойдёт со скриптом, если он не закончит выполняться до следующего запуска задания в кроне? Хорошо, если несколько экземпляров допустимы. А если нет? Как в рамках крона это контролировать?


        1. Areso
          00.00.0000 00:00
          +6

          У человека простой скрипт, он решил свою проблему и его устроило решение.

          Если бы он столкнулся бы с проблемами, он бы пошёл исследовать проблему и методы её решения.

          Опять же, резидентный сервис и ad-hoc скрипт - разные сценарии.
          Тут нужно очень четко формулировать ограничения, чтобы понимать, какие средства будут наилучшими в этих условиях. Зависит от контекста.


          1. ky0
            00.00.0000 00:00
            +1

            Именно поэтому я оформил свой первый комментарий в ироническом стиле, а не начал холиварить и сомневаться в профпригодности автора.


            1. DmitriyB_33 Автор
              00.00.0000 00:00

              Может быть я конечно не так гуглил. В процессе сложилось впечатление, что не хватает обзорной статьи, которая хотя бы показывала связь между сложностью сервиса и инструментов для их запуска на сервере. Очень много информации про докер. Спасибо всем кто оставил комментарии, теперь у меня есть понимание, что вариантов запустить мой простой скрипт есть несколько и можно вполне обойтись без докера.


              1. ky0
                00.00.0000 00:00
                +2

                Связь тут скорее не со сложностью, а с контекстом. В соседних ветках народ может сколько угодно улюлюкать насчёт того, что ради одного скрипта с обвязкой городить контейнеры не стоит, но если, например, вам нужно этот скрипт разложить по нескольким серверам, администрируемым не вами, синхронно обновлять и мочь без проблем проводить диагностику в случае каких-то проблем — лично я бы потратил бы сначала немного времени и докеризировал.


              1. DHeart
                00.00.0000 00:00
                +1

                По идее, если прямо в скрипте загнать вызов первой функции в бесконечный цикл и после вызова прописать time.sleep(N) и проследить, чтоб после отработки итерации в памяти ничего лишнего не оставалось, то и крон не понадобится. Но если скрипт упадет, его никто не поднимет. Отсюда уже можно посмотреть на создание юнитов systemd. На истину не претендую, просто был подобный кейс, решал вот так.

                Вам успехов в начинаниях)


  1. BlackSCORPION
    00.00.0000 00:00
    +1

    Если у кого-то есть решение, как можно сделать тоже
    самое без использования сервера, будет интересно почитать.

    Амазон лямбды могут запускатся по таймеру, думаю аналогичные сервисы от других клауд провайдеров тоже так умеют это не рокет сайнс.


    1. DmitriyB_33 Автор
      00.00.0000 00:00

      Спасибо. Почитаю


  1. vainkop
    00.00.0000 00:00

  1. T1murgar88
    00.00.0000 00:00
    +3

    Я не понимаю что с хабром, одни статьи про Пайтон и qa


  1. Tzimie
    00.00.0000 00:00
    +1

    А просто так, без докера, питон не запустить?


    1. iig
      00.00.0000 00:00
      +2

      Какой же ты хакер без ноутбука девопс без докера? ;)


      1. Tzimie
        00.00.0000 00:00
        +1

        А, понял, то есть дело опять в смузи и цветных носках)


        1. iig
          00.00.0000 00:00
          +1

          Нет, автор же не скрывает, что нагуглил, то и сделал. Попался рецепт с докером - он его применил.


          1. Tzimie
            00.00.0000 00:00
            -1

            То есть карго культ в чистом виде. Вместо самолёта из соломы - докер


            1. iig
              00.00.0000 00:00
              +2

              Только в этом случае самолёт из соломы полетел ;) Скорее забили гвоздь микроскопом.
              То ли ещё будет, когда chatgpt пойдёт в массы ;). Он же будет подсказывать самые трендовые решения.


              1. DmitriyB_33 Автор
                00.00.0000 00:00
                +1

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


                1. Tzimie
                  00.00.0000 00:00

                  А тут просто здравый смысл. Докер полезен если очень хитрая конфигурация, или надо одно и тоже раздавать на разные машины или разными людям. А что-то сделать на одном сервере для себя - точно нет. Отлаживать внутри докера неудобно. Туда пихают что-то готовое как правило


    1. DmitriyB_33 Автор
      00.00.0000 00:00

      Если подскажите или скинете ссылку на реализацию буду признателен.


      1. Tzimie
        00.00.0000 00:00
        +4

        Ловите

        sudo apt-get install python3

        И вам не нужен докер)))


  1. orthlus
    00.00.0000 00:00
    +3

    в целом для этого подойдут облачные функции и тригеры по времени в Яндекс облаке. И квоты там большие

    если очень нужны контейнеры, то там же есть servless containers


  1. Sadok
    00.00.0000 00:00
    +1

    Набираем «crontab –e»

    ... и получаем в глаз, если ты не админ localhost. Это статья про man 5 crontab?


    1. DmitriyB_33 Автор
      00.00.0000 00:00

      Я не являюсь DevOps специалистом, можете пояснить? Не совсем понимаю, что не так с «crontab –e»


      1. lair
        00.00.0000 00:00
        +1

        При чем тут девопс-то? Устройство крона никакого отношения к девопс не имеет.


      1. Sadok
        00.00.0000 00:00
        +1

        Я не зря про localhost упомянул. Когда начинаются странные вещи, то администратору хоста очень весело ползать по всем пользовательским кронам в том числе


    1. Areso
      00.00.0000 00:00
      +1

      у каждого пользователя на хосте - свой кронтаб. Не вижу проблемы :)


      1. Sadok
        00.00.0000 00:00
        +1

        Я не зря про localhost упомянул. Когда начинаются странные вещи, то администратору хоста очень весело ползать по всем пользовательским кронам в том числе


        1. Areso
          00.00.0000 00:00

          Ну тут тоже вопрос - администратор хоста отвечает за ОС хоста (дистрибутив Линукс) или отвечает за всё на хосте, включая приклад? Если шкодничают юзвери, а крайний всегда админ - ну тогда грустно, полностью согласен.


  1. aborouhin
    00.00.0000 00:00
    +4

    Хм... весь смысл docker - закинуть контейнер на сервер и не думать, что там на самóм сервере ещё необходимо для его корректной работы. Так зачем, если уж мы с docker связались (что для данной задачи тоже overkill, но Бог с ним), настраивать crontab на самóм сервере, а не внутри docker-контейнера?.. Настроили crontab внутри контейнера, запустили его один раз - всё.


    1. DmitriyB_33 Автор
      00.00.0000 00:00

      Спасибо. Не знал. Почитаю.


  1. a_f
    00.00.0000 00:00
    +1

    я не проще какую-нить библиотеку типа schedule использовать в самом питоне ?


    1. DmitriyB_33 Автор
      00.00.0000 00:00

      Еще одно предложение в копилку опыта. Спасибо! Рассмотрю такой вариант.