Простір для вивчення нової професії, зростання в кар’єрі або розвитку бізнесу👇🏻
Наша команда пише для вас найкращі та найцікавіші матеріали, які обов’язково допоможуть у вашому навчанні: https://genius.space/lab/
Last updated 1 month, 3 weeks ago
🚛 CI/CD з Github Actions
💭 Зараз зробимо CI/CD автоматизацію, яка при кожному оновленні коду в GitHub репозиторії буде переносити зміни на сервер
🛠 Інструменти
🔀 GitHub Actions - CI/CD платформа, що дозволяє автоматизувати твій build-test-deploy pipeline
🐳 Docker - відкрита платформа для розробки, доставки та запуску додатків (розбирали в пості)
📦 Github Container Registry - зберігає image контейнерів в межах організації чи особистого акаунту, а також дозволяє пов'язати image із репозиторієм
Сама концепція CI/CD набагато ширша, але в рамках даного посту все спрощено: CI - це build контейнера, CD - його release і deploy
• GitHub Actions - в ролі вебхуку на push подію для репозиторію, який буде виконувати наші інструкції
• Docker - для побудови образу (але можна і без нього, наприклад запускати бота з systemd)
• Github Container Registry - для збереження образів (для приватної видимості, в DockerHub на це сильніші обмеження)
✏️ Пишемо конфігурацію
Щоб скористатись GitHub Actions пишуть workflow файли, а вони налаштовані для запуску однієї чи декількох задач
• YAML формат файлу
• Мають знаходитись в .github/workflows/
• Основна структура: події, змінні середовища та завдання
• І workflows і actions можна публікувати та перевикористовувати
Давай розберемо готовий приклад
```
name: Deploy to server
on:
push:
branches: [ "main" ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: /:latest
permissions:
contents: read
packages: write
jobs:
publish:
name: Publish image
runs-on: ubuntu-latest
steps:
\- uses: actions/checkout@v4
\- name: Login
run: |
echo ${{ secrets.GITHUB\_TOKEN }} | docker login ghcr.io \-u ${{ github.actor }} \-\-password\-stdin
\- name: Build and Push
run: |
docker build . \-t ${{ env.REGISTRY }}/${{ env.IMAGE\_NAME }}
docker push ${{ env.REGISTRY }}/${{ env.IMAGE\_NAME }}
deploy:
needs: publish
name: Deploy app
runs\-on: ubuntu\-latest
steps:
\- name: Setup ssh keys
run: |
install \-m 600 \-D /dev/null ~/.ssh/id\_rsa
echo "${{ secrets.SSH\_PRIVATE\_KEY }}" > ~/.ssh/id\_rsa
ssh\-keyscan \-H ${{ secrets.SSH\_HOST }} > ~/.ssh/known\_hosts
\- name: Connect\-pull\-up
run: |
ssh ${{ secrets.SSH\_USER }}@${{ secrets.SSH\_HOST }} << EOF
echo ${{ secrets.GITHUB\_TOKEN }} | docker login ghcr.io \-u ${{ github.actor }} \-\-password\-stdin
cd ${{ secrets.WORK\_DIR }}
docker compose pull
docker compose up \-d
EOF
\- name: Cleanup
run: rm \-rf ~/.ssh
```
• Вказуємо події, при яких він буде працювати workflow (тут це push)
💡За замовчуванням події будуть застосовані до всіх гілок, тому краще вказати конкретну (наприклад main, тоді dev може бути як чорнетка)
• Блок env, як не дивно, служить для вказання змінних середовища
⚠️ Ім'я Docker образів мають бути в нижньому реєстрі. Також тут очікується, що в docker-compose.yaml ім'я образу: //
• Блок permission встановлює права для GITHUB_TOKEN (також доступний через контекст github.token). Це спеціальний токен для автентифікації, що створюється для кожної job
• Блок jobs містить завдання, сприймай їх як етапи. Також вони можуть мати залежності, наприклад тут deploy чекає поки завершиться publish (needs). За замовчуванням завдання виконуються паралельно!
💡 Кожний job працює на окремій віртуальній машині. GitHub-hosted рішення пропонує один із трьох варіантів: Ubuntu, Mac, Windows
• checkout - офіційний action, його можна розуміти як git pull, щоб задача мала доступ до твого коду (використовує GITHUB_TOKEN)
🤫 Тепер про secrets. Їх можна додати в settings репозиторію, щоб використати як змінні середовища
💡Якщо не хочеш давати GitHub приватний SSH ключ, є ідея посилати серверу запит, щоб він сам завантажив і запустив оновлений Docker образ з регістру
🐱 GitHub Actions | Billing
🖼 Publish Docker Images
📝 Workflows syntax
🌱 Життєвий цикл апдейту в aiogram
💭 Зазвичай люди, що починають писати ботів намагаються ловити потрібне повідомлення першим робочим способом і не задумуються над тим, які у них є можливості для організації обробки цих повідомлень
• Що таке апдейт
• Які є способи їх отримання
• Поняття реєстрації та обробника
• Ланцюг обробників
• Роутер і диспетчер - опис, порівняння
• Механізм Dependency Injection
• Детальний розбір мідлваря
• Фільтрація апдейтів
• Хендлер
⏫ Всі ці пункти я спробував розписати у максимально доступному форматі з поясненням різних моментів та описом елементарних помилок
🇺🇦 Стаття українською
https://botfather.dev/news/zhittyevij-cikl-apdejtu-v-aiogram
🌍 Стаття англійською
https://botfather.dev/news/lifecycle-of-an-update-in-aiogram
💫 Мені здається, що представлення цих понять в одній картині спростить написання ботів. Особливо, бачу в цьому сенс для новачків. Крім того, розуміння окремих моментів може бути корисним не тільки для ботів. Приємного читання!
⚡️ Дякую @Latand за його проект та можливість писати там статті
? Офіційний безкоштовний вебхук:
aiohttp, nginx, домен, Let's Encrypt #цікаве
☑️ Це cheatsheet для встановлення бота на вебхук із сертифікатом від Let's Encrypt на свій сервер + його автооновлення + безкоштовний домен
? Перед цим варто прочитати
• Що таке вебхук і які переваги він дає
• Пост про самопідписаний сертифікат
? Трохи теорії
? Let's Encrypt - це безкоштовний, автоматизований і відкритий центр сертифікації, створений некомерційною організацією Internet Security Research Group (ISRG)
? Certbot - це безкоштовна утиліта з відкритим вихідним кодом для автоматичного використання сертифікатів Let's Encrypt
? FreeDNS - середовище, де інші програмісти можуть безкоштовно обмінюватися доменними іменами один з одним. З'явився у 2001 році, тому що його засновник, Джошуа Андерсон, хотів розважитися зі своїм хобі, пов'язаним з доменами
? aiohttp - асинхронний HTTP клієнт/сервер для asyncio та Python
? Переваги офіційного сертифіката над самопідписаним:
• твій сервер визнається всіма (нап. при переході на його адресу в браузері не буде ніяких попереджень про безпеку)
• зручне автооновлення
• при встановленні вебхуку не треба надсилати файл
⬇️ Загалом:
• За допомогою FreeDNS отримуємо безкоштовний домен (для Let's Encrypt необхідно мати домен)
• Сертифікат для вебхуку беремо в Let's Encrypt
• certbot буде автоматично оновлювати наш сертифікат
• nginx буде отримувати POST запити на вебхук і пересилати їх на обробку до бота
• aiohttp буде приймати апдейти бота вже за допомогою Python
? Для різноманіття цього разу візьмемо aiohttp замість FastAPI, бо він більш легший. Але якщо тобі треба будувати API, то залишити FastAPI буде гарним рішенням
✨ Отримання безкоштовного домену
? Такий безкоштовний домен підійде або для тестів або для не дуже великих проектів. Тому, якщо в тебе серйозний проект, краще придбати домен
• Зареєструйся на сайті
• Перейди в розділ субдоменів і натисни «Add a subdomain»
• Переконайся, що в полі «Type» написано А
• У полі «Domain» обери бажаний домен (якщо натиснути «Many many more available» -> «Share Domain Registry», то з'явиться більше варіантів)
Краще обирати не дуже популярні, пізніше скажу чому. Продовжимо:
• в поле «Subdomain» введи назву субдомену (твоя авторська назва), виглядати буде як subdomain.domain
• в поле «Destination» введи IP адресу свого серверу
• після цього підтверди створення субдомену
? Готово, домен є. Далі йди до свого хостинг провайдера і заяви право на цей домен. Наприклад у MVPS на панелі керування сервером є таблиця, в колонку «rDNS» треба ввести домен (ще стаття є)
? Пам'ятай, що необхідно буде почекати декілька хвилин (але іноді годин) поки домен не розійдеться по мережі
? Отримання сертифікату
Далі зайди на свій сервер і встанови certbot. На офіційному сайті є генератор інструкцій, все що треба це обрати систему і софт
В інструкції, команда для отримання сертифікату буде подібною
sudo certbot certonly \-\-nginx
Треба буде обрати домен під який робимо сертифікат і почекати декілька секунд. Після отримання сертифікату certbot встановить таймер для його автооновлення
? Не популярний домен треба брати через те, що в Let's Encrypt є обмеження на частоту оновлення сертифікату і це розповсюджується на субдомени
Перевірити оновлення сертифікату без його фактичного встановлення (чи все добре)
sudo certbot renew \-\-dry\-run
? Конфігурація nginx
Може виглядати наступним чином
```
server {
listen 443 ssl;
server_name YOUR_DOMAIN;
ssl\_certificate /etc/letsencrypt/live/YOUR\_DOMAIN/fullchain.pem;
ssl\_certificate\_key /etc/letsencrypt/live/YOUR\_DOMAIN/privkey.pem;
location / {
proxy\_pass http://SERVER\_IP:AIOHHTP\_PORT;
proxy\_set\_header Host $host;
proxy\_set\_header X\-Real\-IP $remote\_addr;
proxy\_set\_header X\-Forwarded\-For $proxy\_add\_x\_forwarded\_for;
proxy\_set\_header X\-Forwarded\-Proto $scheme;
}
}
```
? Замість YOUR_DOMAIN, SERVER_IP, AIOHTTP_PORT підставляй свої дані (якщо бот використовує Docker, то не забудь відкрити порти)
? На кінець, приклад використання aiohttp для вебхуку можна глянути тут
? Всім привіт, в останні неділі писав бота. Це як мій пет проект, що буде корисний (на мій погляд) будь-якій активній людині в Telegram Якщо коротко - можна зберігати повідомлення будь-якого типу, кастомізувати, і за допомогою інлайн режиму надсилати їх у…
⭐️ Telegram stars #цікаве
? Телеграм зірки - валюта в телеграм, яку можна купувати за реальні гроші та витрачати в месенжері на різні речі
? Переваги у використанні зірок
• Зручність - на відмінну від інших способів оплати, використання зірок набагато зручніше як для користувача так і для сервісу. Користувач може легко поповнити свій баланс зірок через банківську карту (якщо телеграм завантажено з офіційного сайту) чи у Play Market або App Store. Проведення оплати можна зробити в декілька дотиків
• Легка можливість повернення зірок назад на баланс клієнта за допомогою ідентифікатору транзакції
• За допомогою зірок можна оплачувати Telegram Ads та переводити їх в реальні гроші
? Неприємні моменти використання зірок
• Всі цифрові товари, які можна придбати в твоєму сервісі повинні оплачуватись виключно за допомогою зірок (це не стосується фізичних товарів). Тобто, якщо ти продаєш цифрові товари іншими способами, то телеграм може частково (на окремих платформах) або повністю заблокувати доступ до твого сервісу. Теоретично, процес перевірки автоматизувати неможливо, тому це стосується тільки дуже великих проектів у яких є відповідні товари. Це означає, що маленькі сервіси можуть проводити оплату будь-яким способом, але я не рекомендую подібні способи
• Комісія при оплаті зірками від 30% і більше, що руйнує деякі бізнес моделі
• Твій сервіс зобов'язаний брати на себе відповідальність за обслуговування клієнтів і повністю сам вирішувати спірні моменти (зокрема мати команду /paysupport)
• На даний момент, ціна однієї зірки становить 0.013 USD
• Переведення зірок у реальні гроші буде доступно через 21 день після їх отримання сервісом. Це буде пов'язано з криптовалютою і такий механізм працюватиме на платформі Fragment. Поки що, реальних переведень зафіксовано не було, тому деталі невідомі
• Зірки мають час життя в 3 роки з дати їх отримання і якщо їх не витратити, то вони автоматично спишуться з балансу
? Поки що, придбати зірки можна лише під час спроби оплатити чек. Також, зірки йдуть не на баланс власника бота, а на баланс самого бота, який можна переглянути у профілі бота
? Як цим користуватись?
? Важливо не забути додати апдейт типу pre_checkout_query
в дозволені, бо він не встановлюється за замовчуванням
⬇️ Простий приклад коду для створення чеку на оплату 5 зірок (або посилання)
```
from aiogram import Router, F, Bot
from aiogram.filters import Command
from aiogram.types import (
Message,
LabeledPrice,
PreCheckoutQuery,
)
router = Router()
@router.message(Command('start'))
async def create_invoice(msg: Message):
await msg.answer_invoice(
title="Title",
description="Description",
payload="payload",
currency="XTR", # XTR only, don't change
prices=[
LabeledPrice(label="label", amount=5), # 5 telegram stars
],
)
@router.pre_checkout_query()
async def checkout_handler(checkout_query: PreCheckoutQuery):
await checkout_query.answer(ok=True)
@router.message(F.successful_payment)
async def star_payment(msg: Message, bot: Bot):
await bot.refund_star_payment( # for testing auto-recovery of funds
msg.from_user.id,
msg.successful_payment.telegram_payment_charge_id,
)
# What actions, such as:
# - adding a transaction to the database
# - opening access to paid functions
await msg.answer(f"Your transaction id: {msg.successful_payment.telegram_payment_charge_id}")
```
? Прості пункти використання платежів. Ще варто знати, що чеки можуть бути оплачені як один раз так і декілька, детальніше про це можна дізнатись тут
? На 200 підписників зроблю пост на тему: Вебхук із самопідписаним сертифікатом + nginx reverse proxy server, FastAPI
? Деплой ботів та SSH ключі #цікаве
? Деплой - процес розгортання веб-сервісу (в нашому випадку бота) в робочому оточенні (хостинг чи власна інфраструктура)
1️⃣ Різні методи та інструменти
На даний момент є дуже багато різних технологій для деплою і підтримки (CI/CD) програмного забезпечення. Виділяється з них Docker - дуже зручний інструмент для контейнеризації, він дозволяє один раз зібрати образ (image) і на його основі створювати контейнери - ізольовані (на рівні OC, а не hardware) середовища для роботи сервісів. Є параметри, щоб Docker сам запускав контейнери, якщо сервер перезавантажити, перевіряв їх на працездатність і не тільки.
Звичайною практикою буде побачити базу даних в одному контейнері, а основний сервіс в іншому + ще якісь додаткові контейнери - кожен відповідатиме за свою задачу.
Базові образи, наприклад Python, PostgreSQL є на DockerHub, тому якщо треба, докер сам їх завантажить для побудови image. Всі технології прив'язані до якоїсь OC, тому їх багато варіантів + різні версії + lite збірки - можна заплутатися. Але якщо треба - розберешся
2️⃣ Використання
• Встанови докер та запусти його як сервіс
• Напиши Dockerfile - в ньому будуть інструкції для побудови образу
• Якщо в боті є додаткові сервіси (такі як бд, редіс і т.д) створи docker-compose.yaml щоб оркеструвати одразу декількома контейнерами (перед цим прочитай про мережі)
• Дивись на приклади. Попрактикуйся з написанням образів та конфігів для компоузу, але головне розумій що робить та чи інша команда і коли що слід використовувати
• Поцікався багатоетапними збірками (коли образ використовує збудований в цьому ж Dockerfile образ)
• Дізнайся як відкривати порти. Це корисно, якщо треба взаємодіяти з сервісами не заходячи в сам контейнер. Наприклад за допомогою SSH тунелю можна локально в редакторі підключатись до БД в контейнері на сервері
• Подивись що таке профілі, корисна штука за допомогою якої можна вибірково вказати, які сервіси компоузом не треба запускати, якщо ти цього явно не вкажеш
? Збирати образи на сервері є поганою ідеєю, подивитись в сторону Docker Registry
? SSH ключі - шлях до безпечної праці з серверами
? Базова концепція - є клієнт і сервер. Ціль - безпечно обмінюватись даними. Клієнт генерує пару ключів - приватний і публічний. За допомогою базової аутентифікації паролем клієнт поміщає на сервер публічний ключ. Далі можна спробувати з'єднатися за допомогою утиліти ssh. Також на приватний ключ можна додатково накладати пароль. Приватний ключ ніколи, нікому не даємо.
1️⃣ Створення пари ключів
Для цього є різні утиліти. У мене наприклад є ssh-keygen. Команда генерації може виглядати так:
ssh\-keygen \-t rsa \-b 2048 \-f ~/.ssh/key\_name
-t алгоритм генерації ключа
-b довжина ключів в байтах
-f шлях, куди помістити ключі
? Чому назва одна, ключів же 2? Справа в тому, що публічний ключ буде мати назву key_name.pub, а от приватний просто key_name
2️⃣ Організація ключів
? А якщо у нас буде багато серверів, при тому декілька різних ключів для кожного користувача на сервері, все пхати в .ssh?
Для цього в директорії .ssh можна створити файл config. Він допомагає встановити відповідність між ключами та серверами. Наприклад:
```
Host 123.45.67.89
HostName mybot.io
User admin1
IdentityFile ~/.ssh/server1/key.pub
IdentitiesOnly yes
Host 132.89.46.72
HostName 132.89.46.72
User admin2
IdentityFile ~/.ssh/server2/key.pub
IdentitiesOnly yes
...
```
І так далі. Кожен блок відповідає за одну пару ключів.
• Host - IP серверу
• HostName - домен чи IP серверу
• User - аккаунт на сервері
• IdentityFile - шлях до публічного ключа
• IdentitiesOnly - не пробувати інші ключі
3️⃣ Перенесення ключів
? Створили, організували, як перенести їх на сервер?
Наприклад за допомогою scp чи ssh-copy-id. Приклад:
ssh\-copy\-id \-i ~/.ssh/.../key.pub user@ip\_address
? Ключі буде перенесено в домашню директорію user!
Вводимо пароль і ключі вже на сервері у потрібному місці!
? Після встановлення SSH ключів часто прибирають аутентифікацію паролем
?? Docker Guide
? SSH keys
? Всім привіт, в останні неділі писав бота. Це як мій пет проект, що буде корисний (на мій погляд) будь-якій активній людині в Telegram
Якщо коротко - можна зберігати повідомлення будь-якого типу, кастомізувати, і за допомогою інлайн режиму надсилати їх у будь-які чати. Є пошук, приватність, мови
? Ось сам бот @ntosbot
? Кому цікаво, які технології юзав:
• aiogram
• aiogram-dialog
• aiogram_i18n
• PostgreSQL
• psycopg3
• SQLAlchemy
• Alembic
• Redis
• Docker
? Хостинг - https://www.mvps.net/?aff=30539 :D. Поки перша версія, треба тестити, буду радий почути фідбек
? Чи було б цікаво почитати про деплой ботів (Docker, SSH keys)?
Простір для вивчення нової професії, зростання в кар’єрі або розвитку бізнесу👇🏻
Наша команда пише для вас найкращі та найцікавіші матеріали, які обов’язково допоможуть у вашому навчанні: https://genius.space/lab/
Last updated 1 month, 3 weeks ago