Telegram Боты на Aiogram 3.x: Деплой бота через Docker

от автора

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

Дисклеймер

Цель данного руководства — не обучение Docker, а пример использования этой технологии в контекте телеграмм ботов на aiogram 3. Я не буду сильно акцентировать внимание на таких вещах, как слои, volume, docker-compos, bridge и прочей технической информации более глубокого уровня, чем необходимо для деплоя ботов на VPS сервере.

Далее вы получите пример использования Docker и общее описание методов (команд). Если вам нужны мои обучающие публикации по Docker, сообщите мне об этом любым удобным способом.

Подготовка

Для начала вам нужно обзавестись базой данных PostgreSQL. О том, как развернуть ее на VPS сервере, я писал ТУТ. Также потребуется установить Docker. Новичкам будет удобнее поставить Docker Desktop, если с технологией уже знакомы, используйте консольный вариант.

  1. Установите Docker и запустите его.

  2. Проверьте установку командой: docker –version

Если докер установлен, то вы получите ответ с текущей установленной версией. У меня так:

Docker version 26.1.1, build 4cf5afa

Дальше я открою эту папку через Pycharm, но вы можете вводить все команды через CMD, PowerShell, терминал и так далее.

Функциональность бота мы обсуждали ТУТ, сейчас же сосредоточимся именно на Docker.

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

Если вы клонировали репозиторий, то можете обнаружить в нем следующие файлы:

Вы видите знакомую структуру с тремя новыми файлами:

  • .dockerignore

  • DockerFile

  • Makefile

Основной файл — DockerFile. Вот его содержимое:

FROM python  WORKDIR /usr/src/app  COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt  COPY . .  CMD ["/bin/bash", "-c", "python aiogram_run.py"]

Объяснение строк Dockerfile:

  1. FROM python: Использует официальный образ Python.

  2. WORKDIR /usr/src/app: Устанавливает рабочую директорию.

  3. COPY requirements.txt ./: Копирует файл зависимостей.

  4. RUN pip install --no-cache-dir -r requirements.txt: Устанавливает зависимости.

  5. COPY . .: Копирует все файлы.

  6. CMD ["/bin/bash", "-c", "python aiogram_run.py"]: Запускает скрипт.

Немного кулинарной теории

Образ в контексте Docker — это своего рода шаблон или слепок, который содержит всё необходимое для запуска приложения. В образ входят:

  1. Операционная система (или её часть).

  2. Программы и библиотеки, нужные для работы приложения.

  3. Само приложение и его файлы.

Представьте образ как рецепт для приготовления блюда: он содержит все ингредиенты и инструкции, чтобы приготовить это блюдо. Когда вы запускаете контейнер, Docker использует этот образ, чтобы создать рабочую среду для вашего приложения.

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

Контейнер — это запущенный экземпляр образа. Он работает как отдельная маленькая виртуальная машина или изолированная среда, в которой запускается ваше приложение.

Представьте контейнер как кухню, где по рецепту (образу) готовится блюдо (приложение). Контейнеры обеспечивают, чтобы приложение работало одинаково в разных средах, потому что всё необходимое уже упаковано внутри.

Надеюсь, что доступно объяснил.

.dockerignore

Данный файл работает аналогичным образом с .gitignore, с отличием в том, что тут мы настраиваем игнорирование тех файлов, которые мы не будем включать в свой  Docker-образ.

Makefile

Makefile упрощает процесс создания и запуска Docker-контейнера. Пример Makefile:

run: docker run -it -d --env-file .env --restart=unless-stopped --name easy_refer easy_bot_image stop: docker stop easy_refer attach: docker attach easy_refer dell: docker rm easy_refer

Для того чтоб использовать Makefile на операционной системе на которой вы работаете должен быть установлен Make. О том как поставить Make и вообще что это такое я писал в этом посте ССЫЛКА.

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

Нужные команды

Сегодня нам необходимо будет:

  • Создать docker-образ (image)

  • Запустить контейнер на основе этого образа

Для создания docker-образа нам необходим Dockerfile (описали выше). Далее просто переходим в папку где расположен этот файл и вводим такую команду:

docker build -t name_image .

Пояснение:

  1. docker build:

    • Эта часть команды говорит Docker, что нужно построить (создать) образ на основе инструкций из Dockerfile.

  2. -t name_image:

    • Опция -t (или —tag) задает тег для создаваемого образа. Тег состоит из имени и, опционально, версии в формате name:tag. В данном случае образ будет называться name_image. Если версия (тег) не указана, Docker по умолчанию присваивает тег latest.

  3. . (точка):

    • Эта часть указывает контекст сборки. Точка обозначает текущую директорию, то есть Docker будет искать Dockerfile и все необходимые файлы в текущей директории для создания образа.

Пример

docker build -t easy_bot_image .

Так как мы указывали в Dockerfile FROM python – автоматически с docker hub подтянется образ python. Так как python у нас записан без тегов – будет установлена версия latest.

Для того чтоб просмотреть все установленные у вас образы воспользуйтесь командой:

docker images

Один из образов будет тот что вы создали. Далее, для взаимодействия с этим образом вам достаточно будет указывать то имя что вы передавали после -t или его IMAGE ID (достаточно первых 2-3 символов, если они уникальны). Я буду использовать имя образа.

Теперь нам остается создать контейнер и запустить его.

За создание контейнера отвечает команда create, а за запуск start, но мы можем объеденить эти две команды через run (синтаксический сахар).

При выполнении команды run есть обязательный параметр – это имя или id образа, который будет лежать в основе контейнера. Так же есть дополнительные параметры, которые задаются через флаги.

Давайте рассмотрим команду:

docker run -it -d --env-file .env --restart=unless-stopped --name easy_refer easy_bot_image 

Пояснение:

  1. docker run:

    • Запускает новый контейнер на основе указанного Docker-образа.

  2. -it:

    • -i (interactive): Запускает контейнер в интерактивном режиме, позволяя взаимодействовать с его стандартным вводом.

    • -t (tty): Подключает терминал к контейнеру, так что у вас будет доступ к его командной строке.

  3. -d:

    • -d (detached): Запускает контейнер в фоновом режиме (демон).

  4. —env-file .env:

    • Загружает переменные окружения из файла .env, чтобы использовать их внутри контейнера.

  5. —restart=unless-stopped:

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

  6. —name easy_refer:

    • Присваивает контейнеру имя easy_refer.

  7. easy_bot_image:

    • Указывает имя Docker-образа, который используется для создания контейнера. В данном случае это easy_bot_image.

Что делает эта команда:

  • Запускает новый контейнер на основе образа easy_bot_image.

  • Назначает контейнеру имя easy_refer.

  • Загружает переменные окружения из файла .env.

  • Запускает контейнер в интерактивном режиме с подключением терминала, но в фоновом режиме.

  • Настраивает контейнер на автоматический перезапуск, если он завершился с ошибкой, но не перезапускает его при ручной остановке.

Перед запуском моего бота необходимо самостоятельно настроить .env файл (положите его в корень бота).

Вот параметры, которые должны быть в файле:

TOKEN=bot_token ADMINS=список телеграмм айди админов PG_LINK=ссылка на подключение к постгрес ROOT_PASS=доп пароль для работы с базой данных

Видим, что бот запустился. Примечательно то, что даже если бы у вас вообще не стоял Python на операционной системе — данный метод бы отработал и бот был запущен.

Давайте посмотрим какие контейнеры у нас есть (запущенные и нет):

docker ps -a

Видим, что контейнер запущен.

Давайте остановим контейнер, а после удалим его. Затем проверим контейнер:

docker stop easy_refer docker rm easy_refer docker ps -a

А теперь давайте создадим новый контейнер через Make:

make run

Да, получили тот же результат. Согласитесь, что это удобно.

Теперь давайте зайдем в запущенный контейнер и посмотрим, что там происходит:

docker attach easy_refer

Таким образом мы попали во внутреннюю операционную систему нашего контейнера. Внутри мы видим те же логи, что видели бы при обычном запуске. Тут же мы можем остановить контейнер комбинацией клавиш CTRL+C (если внутри контейнера не происходит ничего, то он сам останавливается) или выйти из интерактивного режима (обратно в фон вывести контейнер).

Для того нужно нажать комбинацию клавиш CTRL+p, а затем CTRL+q.

Обратите внимание. Если бы при создании контейнера мы не указали флаг -it, то возможности выйти из интерактивного режима через указанную выше комбинацию клавиш не было бы.

Давайте снова удалим наш контейнер, чтоб не занимал место, и приступим к непосредственному деплою на VPS сервер.

Отправка образа на Docker hub

  1. Выполняем авторизацию на сайте Docker hub

  2. Переименовываем свой image (образ) на имя в таком формате:

docker_username/image_name

Пример в моем случае:

docker tag easy_bot_image yakvenalexx/easy_bot_image

Авторизация:

docker login

Теперь делаем push нашего образа

docker push yakvenalexx/easy_bot_image

Видим, что все прошло успешно. Теперь давайте зайдем в профиль на docker hub и посмотрим появиился ли у нас там репозиторий:

Репозиторий на месте, а значит что мы завершили подготовку к деплою. Теперь можно удалить ненужные образы с локального компьютера. В моем случае это:

docker rmi easy_bot_image yakvenalexx/easy_bot_image

Отлично! Теперь давайте войдем на свой VPS сервер (я буду пользоваться Ubuntu) и запустим там Docker (на примере вход по SSH с логином и паролем).

Вход по SSH:

ssh user@host password

Обновление и установка Docker:

sudo apt update -y  sudo apt upgrade -y sudo apt install apt-transport-https ca-certificates curl software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt update sudo apt install docker-ce sudo systemctl status docker

Статус должен выглядеть примерно так:

Установка Make:

sudo apt install make

Теперь можно проверить версии docker и make.

docker --version make --verson

Если в обоих случаях видим версию – значит все установлено.

Все ок

Все ок

Отлично. Теперь давайте создадим папку с именем my_bot и закинем в него файл .env и Makefile.

cd ../home mkdir my_bot cd my_bot

Теперь скачаем образ. Для этого мы можем зайти в профиль на Docker hub и найти там кнопку копирования:

Жмем на нее и команду вставляем в терминал на VPS сервере

Жмем на нее и команду вставляем в терминал на VPS сервере
docker pull yakvenalexx/easy_bot_image

Тут обратите внимание. Проверьте, чтоб файл Makefile содержал корректное название образа. Если это не так, то откорректируйте файл на сервере через nano или закиньте корректный файл любым удобным для себя способом.

Выполняем запуск:

make run

Заглянем в контейнер и убедимся, что все работает:

make attach
Сразу будет чисто. Важно чтоб после подключения attach ваша программа выдала какие-то логи.

Сразу будет чисто. Важно чтоб после подключения attach ваша программа выдала какие-то логи.

Заключение

Docker действительно упрощает создание и деплой приложений в изолированных контейнерах. С помощью этого руководства вы сможете запустить своего бота на VPS сервере, даже если раньше ничего не знали о Docker. Надеюсь, что вы теперь видите, насколько эта технология может облегчить вашу работу и сделать её более эффективной.

Если у вас возникли вопросы или нужна дополнительная информация, не стесняйтесь обращаться.

Хотели бы вы увидеть цикл моих статей на тему Docker? Подписывайтесь на обновления и ставьте лайки, чтобы не пропустить новые материалы. Ваша поддержка очень важна для меня, ведь без неё все усилия, потраченные на создание контента, теряют смысл.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Хотели бы вы увидеть цикл моих статей на тему Docker?

46.67% Да7
53.33% Нет8

Проголосовали 15 пользователей. Воздержавшихся нет.

ссылка на оригинал статьи https://habr.com/ru/articles/823714/


Комментарии

Добавить комментарий

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