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

Ссылка на GitHub

BotEnvrot на GitHub

Введение

В современном мире разработки программного обеспечения, где количество и сложность проектов постоянно растут, управление инфраструктурой становится все более трудоемким. Возникает потребность в быстром и гибком доступе к конфигурационным файлам, особенно когда вы находитесь вне офиса. Именно эту проблему решает наш проект: Telegram-бот для управления Docker-контейнерами.

Проблематика

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

Решение

Наш Telegram-бот предоставляет удобный интерфейс для управления Docker-контейнерами прямо из вашего смартфона. Благодаря этому, вы можете быстро и безопасно менять конфигурацию ваших проектов, не зависимо от вашего местоположения.

Архитектура

  1. Сервер: На сервере хранятся все ваши проекты в директории вида /home/user/git/<имя_проекта>/, где расположены файлы docker-compose.yml и .env.

  2. Telegram-бот: Внутри бота имеется каталог CFG, структурированный следующим образом: ./cfg/<имя_проекта>/<вариант_env>. Это позволяет хранить различные варианты конфигураций для каждого проекта.

Работа с ботом

  • Отправьте команду /start для начала работы.

  • Выберите нужный проект из списка.

  • Выберите нужный env-файл или выполните другую команду (например, остановить или перезапустить контейнер).

Ключевые компоненты

Инициализация и настройка логгирования

# Получение значения переменной DEBUG из окружения
DEBUG = os.environ.get("DEBUG")

# Настройка логгирования в зависимости от DEBUG
if DEBUG:
    logging.basicConfig(
        level=logging.INFO,
        # ...
    )
else:
    logging.basicConfig(
        level=logging.ERROR,
        # ...
    )

Здесь мы настраиваем логгирование в зависимости от переменной окружения DEBUG. Это позволяет контролировать уровень детализации логов.

Инициализация бота и диспетчера

# Получение токена бота и ID администратора из переменных окружения
BOT_API_TOKEN = os.environ.get("BOT_API_TOKEN")
ADMIN_ID = os.environ.get("ADMIN_ID")

# Инициализация бота и диспетчера
bot = Bot(token=BOT_API_TOKEN)
dp = Dispatcher()

Здесь мы инициализируем бота и диспетчера, используя токен и ID администратора из переменных окружения.

Обработка команд

@dp.message(CommandStart)
async def handle_start(msg: types.Message):
    # Проверка прав доступа пользователя
    if msg.from_user.id != int(ADMIN_ID):
        await msg.answer("You are not allowed to use this bot.")
        return
    # ...

При получении команды /start, бот проверяет, является ли пользователь администратором. Если да, то предлагает список доступных проектов.

Выполнение Docker-команд

def docker_command(*args):
    try:
        subprocess.run(["docker-compose", *args], check=True)
        return True
    except subprocess.CalledProcessError as e:
        logger.exception(f"Exception: {e}")
        return False

Эта функция выполняет команды Docker с помощью модуля subprocess. Она возвращает True, если команда выполнена успешно, и False в противном случае.

Упаковка проекта с использованием Poetry в Docker

Структура Dockerfile

Использование официального образа Python

FROM python:3.11

Здесь мы используем официальный образ Python версии 3.11 как базовый образ.

Установка переменных окружения для Poetry

ENV POETRY_HOME="/opt/poetry" \
    POETRY_VIRTUALENVS_IN_PROJECT=true \
    POETRY_NO_INTERACTION=1

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

Добавление Poetry в PATH

ENV PATH="$POETRY_HOME/bin:$HOME/.local/bin:$PATH"

Добавляем путь к исполняемому файлу Poetry в переменную окружения PATH.

Установка Poetry

RUN pip install poetry

Устанавливаем Poetry с помощью pip.

Установка рабочего каталога и копирование исходного кода

RUN mkdir /app
WORKDIR /app
COPY . /app

Здесь мы создаем рабочий каталог /app и копируем в него исходный код проекта.

Установка зависимостей

COPY pyproject.toml poetry.lock /app/
RUN poetry install --no-dev --no-root --no-interaction --no-ansi -vvv

Копируем файлы pyproject.toml и poetry.lock в рабочий каталог и устанавливаем зависимости с помощью Poetry.

Запуск приложения

ENTRYPOINT ["poetry", "run", "python3", "botenv.py"]

Задаем точку входа для запуска приложения.

Интеграция Docker и Docker Compose

Структура файла docker-compose.yml

Версия и сервисы

version: '3.8'
services:
  bot_env:

Здесь мы используем версию 3.8 файла Compose и определяем один сервис bot_env.

Построение образа

    build:
      context: .
      dockerfile: Dockerfile

Контекст сборки установлен на текущую директорию, а Dockerfile указан явно.

Имя и тег образа

    image: omeh2003/bot_env:latest

Образ будет сохранен с именем omeh2003/bot_env и тегом latest.

Тома

    volumes:
      - "./data/:/app/data/"
      - "./cfg/:/app/cfg/"
      - "/home/omeh2003/git/:/app/git/"
      - "./.env:/app/.env"

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

Проверка работоспособности

    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5000/"]
      interval: 1m30s
      timeout: 10s
      retries: 3

Healthcheck выполняет проверку доступности приложения каждые 1 минуту 30 секунд, с таймаутом в 10 секунд и до 3 попыток.

Перезапуск и порты

    restart: always
    ports:
      - "5000:5000"

Сервис будет автоматически перезапускаться, и порт 5000 хоста будет проброшен на порт 5000 контейнера.

Теперь у нас есть команды

Д

  1. docker-compose build: Эта команда собирает образ для приложения на основе информации из файла Dockerfile. Она учитывает все параметры, указанные в разделе build вашего файла docker-compose.yml.

  2. docker-compose up: Эта команда запускает приложение, используя настройки из файла docker-compose.yml. Если образ не был предварительно собран, команда сначала выполнит сборку. Флаг -d позволяет запустить контейнеры в фоновом режиме.

  3. docker-compose down: Эта команда останавливает все запущенные контейнеры, удаляет их и также удаляет созданные сети, объявленные в docker-compose.yml.

Эти команды значительно упрощают процесс развертывания и управления приложением, делая его более воспроизводимым и изолированным.

Ссылка на GitHub

BotEnvrot на GitHub

Канал в телеграмме

Ну и конечно Twitter

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


  1. antirek
    25.09.2023 04:42
    +2

    во время встречи или переговоров

    интересная мотивация, конечно: ни конфигурировать нормально, ни внимание встрече уделить )))

    хотя аналог ctop'а в тг может быть и нужен


    1. semenovs Автор
      25.09.2023 04:42

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

      про с_top практически в точку

      есть уже функционал, который занимается мониторингом внутри контейнера. Снаружи контейнера ,собиранием логов отчётов и получается, что его нужно копировать каждый свой новый проект, и я его со временем просто весь Перенесу в этого Бота и они он будет там. А так он есть и сейчас тоже работает и очень хорошо.


  1. semenovs Автор
    25.09.2023 04:42

    Странно что никто не написал что внутри докер контейнера это работать не будет. Видимо сам проект никто не посмотрел )


    1. hrad
      25.09.2023 04:42

      Кто захочет - тот разберётся, соберёт образ с docker client, прокинет docker.sock да перепишет аккуратно. Может быть даже применит Docker SDK for Python. ;)


    1. avkritsky
      25.09.2023 04:42

      День добрый. Можно отредактировать файл /lib/systemd/system/docker.service, заменив параметр ExecStart следующей строкой:
      ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 $DOCKER_OPTS
      и перезапустить сервис докера (systemctl daemon-reload и service docker restart)
      Тогда у Вас появится возможность стучать в API-шку Вашего серверного докера, а сам проект запускать в… докере. Ну, как возможный вариант.


  1. ReDev1L
    25.09.2023 04:42

    Чёт жесть какая то, есть много api/sdk вместо команд подпроцессом. Причём на любой докер хост.

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


    1. jlexand
      25.09.2023 04:42

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