Автоматическое обновление ботов через CI/CD
Введение
Ручной деплой — это копирование файлов по SSH и перезапуск сервиса. Это работает для одного бота, но не масштабируется. CI/CD автоматизирует весь процесс: push в Git → тесты → сборка → деплой.
Зачем нужен CI/CD для ботов
- Скорость: обновление за секунды вместо минут
- Надёжность: автоматические тесты перед деплоем
- Консистентность: каждый деплой одинаковый
- Откат: легко вернуться к предыдущей версии
- Аудит: история всех изменений в Git
Вариант 1: GitHub Actions
Самый популярный CI/CD для open-source и приватных проектов.
Пример для Go-бота
# .github/workflows/deploy.yml
name: Deploy Bot
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Test
run: go test ./...
- name: Build
run: |
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -o mybot ./cmd/bot
- name: Deploy
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_KEY }}
script: |
systemctl stop mybot
cp /tmp/mybot /home/botuser/mybot
systemctl start mybot
- name: Upload binary
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_KEY }}
source: "mybot"
target: "/tmp/"
Секреты
Добавьте в Settings → Secrets:
SERVER_HOST— IP сервераSERVER_USER— пользователь SSHSSH_KEY— приватный SSH-ключ
Вариант 2: GitLab CI
# .gitlab-ci.yml
stages:
- test
- build
- deploy
test:
stage: test
image: golang:1.22
script:
- go test ./...
build:
stage: build
image: golang:1.22
script:
- CGO_ENABLED=0 go build -o mybot ./cmd/bot
artifacts:
paths:
- mybot
deploy:
stage: deploy
only:
- main
script:
- apt-get update && apt-get install -y openssh-client
- scp mybot $SERVER_USER@$SERVER_HOST:/home/botuser/mybot
- ssh $SERVER_USER@$SERVER_HOST 'sudo systemctl restart mybot'
Вариант 3: Webhook-деплой
Для простых сценариев можно использовать webhook — HTTP-запрос от GitHub при push:
Настройка на сервере
# deploy-hook.sh
#!/bin/bash
cd /home/botuser
git pull origin main
go build -o mybot ./cmd/bot
sudo systemctl restart mybot
echo "Deployed at $(date)"
Настройте webhook в GitHub: Settings → Webhooks → URL вашего сервера.
Zero-downtime деплой
Простой systemctl restart вызывает секунды даунтайма. Для zero-downtime:
Graceful shutdown
Бот должен обрабатывать SIGTERM:
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGTERM)
defer cancel()
// Запуск бота с контекстом
bot.Start(ctx)
// При SIGTERM — завершаем текущие запросы
<-ctx.Done()
bot.GracefulStop()
Blue-green деплой
- Запустите новую версию на другом порту
- Проверьте health check
- Переключите трафик
- Остановите старую версию
Rollback — откат к предыдущей версии
Хранение артефактов
Сохраняйте последние N бинарников:
# При деплое
cp mybot mybot.$(date +%Y%m%d%H%M%S)
ls -t mybot.* | tail -n +6 | xargs rm -f # Оставляем 5 последних
Откат
# Список версий
ls -la mybot.*
# Откат к предыдущей
cp mybot.20260307120000 mybot
sudo systemctl restart mybot
CI/CD в BotOps
BotOps упрощает CI/CD до минимума:
- Webhook-деплой: BotOps предоставляет URL, который можно добавить в GitHub Actions
- Загрузка бинарника через API:
curl -X POST https://tgbotops.ru/api/deploy -F "binary=@mybot" - Автоматический rollback: если новая версия не проходит health check, BotOps откатывает к предыдущей
- История деплоев: кто, когда, какую версию задеплоил
Никаких SSH-ключей в CI, никаких скриптов деплоя. Один HTTP-запрос — и бот обновлён.
Лучшие практики
- Всегда тестируйте перед деплоем —
go test,pytest,npm test - Деплойте только из main/master — не деплойте из feature-веток
- Используйте версионирование — теги Git или семантическое версионирование
- Мониторьте после деплоя — проверяйте логи первые 5 минут
- Имейте план отката — знайте как быстро вернуть предыдущую версию
Заключение
CI/CD для Telegram-ботов — это инвестиция, которая окупается с первого деплоя. GitHub Actions или BotOps webhook — выбирайте инструмент по сложности вашего проекта.
Попробуйте BotOps — CI/CD для ботов без конфигурации.