HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>Привет! Это вторая моя статья о новом проекте - telegram bot на python, по продаже товаров. В<a>первой части</a>я описал, с чего начал этот проект и какой был финальный результат. Сегодня я хочу поговорить о CI/CD проекта.</p>
1 <p>Привет! Это вторая моя статья о новом проекте - telegram bot на python, по продаже товаров. В<a>первой части</a>я описал, с чего начал этот проект и какой был финальный результат. Сегодня я хочу поговорить о CI/CD проекта.</p>
2 <p>Когда проект достиг стадии MVP (minimum valuable product, минимально жизнеспособный продукт) - очень хотелось вывести его в свет. Для того, чтобы бот постоянно работал, для первых пользователей (тут кто-то был слишком оптимистичен, без рекламы к боту пользователи не придут) и для того, чтобы была возможность выкатывать остальную функциональность маленькими итерациями. Время делать CI/CD.</p>
2 <p>Когда проект достиг стадии MVP (minimum valuable product, минимально жизнеспособный продукт) - очень хотелось вывести его в свет. Для того, чтобы бот постоянно работал, для первых пользователей (тут кто-то был слишком оптимистичен, без рекламы к боту пользователи не придут) и для того, чтобы была возможность выкатывать остальную функциональность маленькими итерациями. Время делать CI/CD.</p>
3 <p>И снова хотел бы напомнить, что я не профессиональный DevOps, а всего лишь тестировщик. Поэтому текст ниже - всего лишь мой опыт, а не руководство, как делать правильно бота профессионально.</p>
3 <p>И снова хотел бы напомнить, что я не профессиональный DevOps, а всего лишь тестировщик. Поэтому текст ниже - всего лишь мой опыт, а не руководство, как делать правильно бота профессионально.</p>
4 <h3>Начнем с CI</h3>
4 <h3>Начнем с CI</h3>
5 <p>Под CI я понимаю запуск тестов, сборку docker image и публикацию артефактов - тех самых images - в репозиторий. Решил не использовать сторонних сервисов, а сделать все на основе GitHub. В целом, как работать с GitHub Actions, можно почитать в<a>официальной документации</a>, тут я попытаюсь описать неочевидные для меня вещи.</p>
5 <p>Под CI я понимаю запуск тестов, сборку docker image и публикацию артефактов - тех самых images - в репозиторий. Решил не использовать сторонних сервисов, а сделать все на основе GitHub. В целом, как работать с GitHub Actions, можно почитать в<a>официальной документации</a>, тут я попытаюсь описать неочевидные для меня вещи.</p>
6 <p>Первая неочевидная вещь - как опубликовать docker image в реестр. Я пробовал несколько actions, пытался писать свой скрипт и, в конечном итоге, остановился на официальном<a>Build and push Docker images</a>:</p>
6 <p>Первая неочевидная вещь - как опубликовать docker image в реестр. Я пробовал несколько actions, пытался писать свой скрипт и, в конечном итоге, остановился на официальном<a>Build and push Docker images</a>:</p>
7 <p>Вторая неочевидная вещь - secrets.PACKAGE_REGISTRY_TOKEN. В интернете разработчики используют secrets.github_token - это стандартный токен, с которым пакет соберется и, даже, опубликуется в вашем реестре. Проблема лишь в том, что после публикации пакета не срабатывается триггер у других actions. В моем случае должен был запуститься следующий workflow для CD. Чтобы триггер сработал, нужно создать новый секрет, в моем случае secrets.PACKAGE_REGISTRY_TOKEN и дать ему права на чтение/запись в реестр.</p>
7 <p>Вторая неочевидная вещь - secrets.PACKAGE_REGISTRY_TOKEN. В интернете разработчики используют secrets.github_token - это стандартный токен, с которым пакет соберется и, даже, опубликуется в вашем реестре. Проблема лишь в том, что после публикации пакета не срабатывается триггер у других actions. В моем случае должен был запуститься следующий workflow для CD. Чтобы триггер сработал, нужно создать новый секрет, в моем случае secrets.PACKAGE_REGISTRY_TOKEN и дать ему права на чтение/запись в реестр.</p>
8 <blockquote><h3>Также интересно:</h3>
8 <blockquote><h3>Также интересно:</h3>
9 <p><a>Как создать бота в Telegram</a>: большая инструкция</p>
9 <p><a>Как создать бота в Telegram</a>: большая инструкция</p>
10 </blockquote><h3>Переходим к CD</h3>
10 </blockquote><h3>Переходим к CD</h3>
11 <p>В моем случае CD - это доставка артефактов на сервер, миграция базы, запуск приложения. Возможности автоматического отката или бесшовной поставки - нет, да она и не нужна пока. В случает с CI, использовался GitHub-ранер. В бесплатной версии GitHub пользователю предоставляется несколько машино\часов для сборки проектов, чего вполне достаточно для домашнего проекта. Но для CD нужен собственный ранер, который возможно занять на постоянной основе, и на котором будет запущен весь проект.</p>
11 <p>В моем случае CD - это доставка артефактов на сервер, миграция базы, запуск приложения. Возможности автоматического отката или бесшовной поставки - нет, да она и не нужна пока. В случает с CI, использовался GitHub-ранер. В бесплатной версии GitHub пользователю предоставляется несколько машино\часов для сборки проектов, чего вполне достаточно для домашнего проекта. Но для CD нужен собственный ранер, который возможно занять на постоянной основе, и на котором будет запущен весь проект.</p>
12 <h3>Добавляем свой runner в GitHub</h3>
12 <h3>Добавляем свой runner в GitHub</h3>
13 <p>Для этого проекта использовались сервера<a>Digital Ocean</a>, так что ниже изложена инструкция по добавлению Docker droplet в качестве ранера к существующему проекту:</p>
13 <p>Для этого проекта использовались сервера<a>Digital Ocean</a>, так что ниже изложена инструкция по добавлению Docker droplet в качестве ранера к существующему проекту:</p>
14 <ol><li>После создания дроплета Docker 5:19.03.1~3 on 18.04, заходим на него через ssh;</li>
14 <ol><li>После создания дроплета Docker 5:19.03.1~3 on 18.04, заходим на него через ssh;</li>
15 <li>Первое, что нужно сделать - добавить пользователя, так как GitHub Runner не позволяет запустить агент от root;</li>
15 <li>Первое, что нужно сделать - добавить пользователя, так как GitHub Runner не позволяет запустить агент от root;</li>
16 </ol><p>$ adduser github</p>
16 </ol><p>$ adduser github</p>
17 <ol><li>Вводим пароль и заполняем информацию о пользователе. Или можно оставить ее пустой;</li>
17 <ol><li>Вводим пароль и заполняем информацию о пользователе. Или можно оставить ее пустой;</li>
18 <li>Добавляем пользователя в группы<a>sudo</a>и<a>docker</a>;</li>
18 <li>Добавляем пользователя в группы<a>sudo</a>и<a>docker</a>;</li>
19 </ol><p>$ adduser github sudo $ sudo usermod -aG docker github $ newgrp docker</p>
19 </ol><p>$ adduser github sudo $ sudo usermod -aG docker github $ newgrp docker</p>
20 <ol><li>Логинимся только что созданным пользователем;</li>
20 <ol><li>Логинимся только что созданным пользователем;</li>
21 </ol><p>$ sudo su - github</p>
21 </ol><p>$ sudo su - github</p>
22 <ol><li>Скачиваем и устанавливаем ранер, как указанно в инструкции<em>Settings -&gt; Actions -&gt; Add runner</em>. Имена ранера и рабочей директории можно оставить со значениями по умолчанию;</li>
22 <ol><li>Скачиваем и устанавливаем ранер, как указанно в инструкции<em>Settings -&gt; Actions -&gt; Add runner</em>. Имена ранера и рабочей директории можно оставить со значениями по умолчанию;</li>
23 <li>Чтобы запустить ранер как сервис, останавливаем текущий скрипт Ctrl+C;</li>
23 <li>Чтобы запустить ранер как сервис, останавливаем текущий скрипт Ctrl+C;</li>
24 <li>Устанавливаем сервиса ранера;</li>
24 <li>Устанавливаем сервиса ранера;</li>
25 </ol><p>$ ./svc.sh install</p>
25 </ol><p>$ ./svc.sh install</p>
26 <ol><li>Запускаем ранер как сервис;</li>
26 <ol><li>Запускаем ранер как сервис;</li>
27 </ol><p>$ ./svc.sh start</p>
27 </ol><p>$ ./svc.sh start</p>
28 <ol><li>В workflow yaml файле меняем runs-on: ubuntu-latest на runs-on: self-hosted;</li>
28 <ol><li>В workflow yaml файле меняем runs-on: ubuntu-latest на runs-on: self-hosted;</li>
29 </ol><h3>Реализация Deploy Workflow</h3>
29 </ol><h3>Реализация Deploy Workflow</h3>
30 <p>Идея такая, что должно быть два workflow. Первый - CI, срабатывает на каждый комит в master-ветку. Он собирает артефакты и публикует их в репозиторий. Второй - CD, срабатывает на публикацию пакета в реестр и дальше доставляет этот пакет на специальный агент. Так как это бот-магазин, то CD workflow может быть несколько (по одному на каждый магазин). Это основная причина, почему сборку и доставку разделил на два отдельных процесса.</p>
30 <p>Идея такая, что должно быть два workflow. Первый - CI, срабатывает на каждый комит в master-ветку. Он собирает артефакты и публикует их в репозиторий. Второй - CD, срабатывает на публикацию пакета в реестр и дальше доставляет этот пакет на специальный агент. Так как это бот-магазин, то CD workflow может быть несколько (по одному на каждый магазин). Это основная причина, почему сборку и доставку разделил на два отдельных процесса.</p>
31 <p>Ниже приведен пример, как указать в yaml файле тригер на публикацию пакета. И как запускать флоу на личном ранере</p>
31 <p>Ниже приведен пример, как указать в yaml файле тригер на публикацию пакета. И как запускать флоу на личном ранере</p>
32 <p>Дальше выполняются шаги с docker-compose по обновлению приложения. Шаги следующие: остановить приложение, забрать последнюю версию артефактов, мигрировать базу, запустить новую версию приложения.</p>
32 <p>Дальше выполняются шаги с docker-compose по обновлению приложения. Шаги следующие: остановить приложение, забрать последнюю версию артефактов, мигрировать базу, запустить новую версию приложения.</p>
33 <p>На данный момент бот постоянно работает и быстро обновляется после выхода новой версии.</p>
33 <p>На данный момент бот постоянно работает и быстро обновляется после выхода новой версии.</p>
34 <p>Надеюсь, вам было полезно и познавательно. Тема не очень простая, так что любые вопросы и замечания оставляйте в комментариях под этим постом.</p>
34 <p>Надеюсь, вам было полезно и познавательно. Тема не очень простая, так что любые вопросы и замечания оставляйте в комментариях под этим постом.</p>
35 <p>Также, если вам интересно следить за дальнейшим развитием этого проекта, то в<a>telegram канале</a>я публикую маленькие заметки по этой теме.</p>
35 <p>Также, если вам интересно следить за дальнейшим развитием этого проекта, то в<a>telegram канале</a>я публикую маленькие заметки по этой теме.</p>