Деплой – это развёртывание программного обеспечения, то есть это все действия, которые делают программную систему готовой к использованию.
Деплой телеграм-бота – это размещение его на сервере или на хостинге.
Итак, стартовые условия:
- хостинг на
Beget
- к хостингу привязан домен
- для домена выпущен бесплатный SSL-сертификат Let’s Encrypt
Начинаем установку Flask.
Установка Flask на Beget
Включаем SSH в настройках хостинга (если он выключен).
Подключаемся к хостингу через SSH. Это можно сделать прямо из панели управления хостингом: у Бегет встроен терминал прямо тут – мега-удобная штука.
Я делаю это через программу Putty.
В поле “hostname (or IP address)” вводим:
<логин-к-хостингу>@domain.ru
То есть в моем конкретно случае:
<логин-к-хостингу>@hosting-telegram-bota.ru
Нажимаем Open, вводим пароль от хостинга и заходим на хостинг через SSH:
Затем нам нужно перейти в Docker, выполняем команду:
ssh localhost -p222
Еще раз потребуется ввести пароль от хостинга, и если всё ОК – видим надпись (docker) в скобочках.
Теперь переходим в папку сайта, в моем случае команда выглядит так:
cd hosting-telegram-bota.ru
Вы всегда можете подсмотреть, где сейчас находитесь в помощью команды:
ls -l
Итак, зашли внутрь папки hosting-telegram-bota.ru
Теперь создадим папку .venv
командой
mkdir .venv
Обновим pip командой
python3 -m pip install --upgrade pip
Активируем виртуальное окружение. Сначала команда:
pip install pipenv
Затем
pipenv shell
Затем переходим в папку .venv
cd .venv
Выполняем
source bin/activate
Если посмотреть через менеджер файлов – то на хостинге у нас такая картина:
и внутри папки .venv тоже кое-что появилось:
Продолжаем работу в консоли через Putty.
Нужно узнать путь к Python, который мы позже пропишем в настройках Flask. Выполните команду:
which python3
и запишите куда-то путь, который вам покажет.
Например, что-то такое:
/home/h/<логин_к_хостингу>/hosting-telegram-bota.ru/.venv/bin/python3
Установим Flask.
python3 -m pip install flask
Установим библиотеку Requests:
pip install requests
Также на этом этапе возможно вам потребуется установить библиотеки, необходимые для работы вашего бота. Тем более, что бот может быть написан с использованием разных вспомогательных фреймворков – Aiogram, Telebot и т.д.
Выйдем из папки .venv
на уровень выше
cd ..
И начнем создавать структуру папок:
.
└── hosting-telegram-bota.ru
├── HelloFlask
│ └── __init__.py
├── .htaccess
├── passenger_wsgi.py
└── tmp
└── .venv
└── Pipfile
└── public_html
Создаем две директории HelloFlask и tmp.
mkdir HelloFlask tmp
Теперь, если посмотреть через File Manager Beget, у нас такая структура папок внутри папки сайта “../hosting-telegram-bota.ru”
Также создаем 2 файла:
touch .htaccess
touch passenger_wsgi.py
Параллельно, если не уверенно себя чувствует с консолью, можно проверять изменения через файловый менеджер хостинга, не забываем кнопку “Обновить”, чтобы увидеть изменения.
Здесь же (в менеджере файлов Бегет) я открою файлы на редактирование.
Сначала .htaccess
В файле .htaccess
пишем следующие строки, где во второй – путь к нашему Python
, который мы узнали ранее через команду which python3
PassengerEnabled On
PassengerPython /home/h/<логин_к_хостингу>/hosting-telegram-bota.ru/.venv/bin/python3
Теперь редактируем файл passenger_wsgi
# -*- coding: utf-8 -*-
import sys, os
# указываем директорию с проектом
sys.path.append('/home/<ваша_буква>/<логин_к_хостингу>/hosting-telegram-bota.ru/HelloFlask')
# указываем директорию с библиотеками, куда поставили Flask
sys.path.append('/home/<ваша_буква>/<логин_к_хостингу>/.local/lib/python3.6/site-packages')
from HelloFlask import app as application
# Когда Flask стартует, он ищет application.
# Если не указать 'as application', сайт не заработает
from werkzeug.debug import DebuggedApplication
# Опционально: подключение модуля отладки
application.wsgi_app = DebuggedApplication(application.wsgi_app, False)
# Опционально: включение модуля отадки
application.debug = False
# Опционально: True/False устанавливается по необходимости в отладке
Также я меняю для обоих файлов права на 644.
Переходим в папку HelloFlask
cd HelloFlask
Создаём там файл __init__.py
touch __init__.py
Открываем его на редактирование и пишем:
from flask import Flask
app = Flask(__name__)
@app.route('/python-bot/')
def hello_world():
return 'Hello Flask!'
if __name__ == '__main__':
app.run()
Обратите внимание, я задал route /python-bot/
, который будет использован потом при добавлении вебхука для телеграм-бота.
Сохраняем и также изменяем атрибуты доступа на 644.
Остались последние приготовления перед проверкой – запустилось ли наше Flask-приложение.
Возвращаемся в корневую директорию
cd ..
Выполняем последние команды:
ln -s public_html public
И запуск (ре-старт) Flask:
touch tmp/restart.txt
Эта команда (touch tmp/restart.txt
) понадобится нам каждый раз, когда мы будем вносить какие-то изменения, чтобы перезапустить Flask.
Не забывайте выполнять ее, иначе изменения применяться не будут.
Также, не забывайте про права на файлы (chmod 644) и возможные другие проблемы. Важна каждая деталь, например, кодировка файлов.
Теперь проверим – работает ли Flask
. Откроем в браузере наш сайт на той странице, адрес которой указали в __init__.py
.
Если всё OK, увидим “Hello Flask!”
Запускаем телеграм бота на хостинге
Ок, Flask работает. Теперь заменим код в файле __init__.py
на код нашего бота.
Я сделал второго телеграмм бота, чтобы на хостинге у нас работал бот на Python
с похожим функционалом, как и тот, что вначале был сделан на PHP
.
Вот такой код я помещу в __init__.py
from flask import Flask, render_template from flask import request from flask import Response import requests TOKEN = "<токен бота>" app = Flask(__name__, template_folder='../public_html') def tel_parse_message(message): print("message-->",message) try: chat_id = message['message']['chat']['id'] txt = message['message']['text'] print("chat_id-->", chat_id) print("txt-->", txt) return chat_id,txt except: print("NO text found-->>") def tel_send_message(chat_id, text): url = f'https://api.telegram.org/bot{TOKEN}/sendMessage' payload = { 'chat_id': chat_id, 'text': text } r = requests.post(url,json=payload) return r def tel_send_image(chat_id): url = f'https://api.telegram.org/bot{TOKEN}/sendPhoto' payload = { 'chat_id': chat_id, 'photo': "https://hosting-telegram-bota.ru/pic/pss-python.jpg", 'caption': "Жми /more" } r = requests.post(url, json=payload) return r def tel_send_inlineurl(chat_id): url = f'https://api.telegram.org/bot{TOKEN}/sendMessage' payload = { 'chat_id': chat_id, 'text': "Добро пожаловать в бота!\nСделано на Python.\nВашему боту нужен хостинг с поддержкой:", 'reply_markup': { "inline_keyboard": [ [ {"text": "Python", "url": "https://hosting-telegram-bota.ru/python"}, {"text": "Node JS", "url": "https://hosting-telegram-bota.ru/"} ], [ {"text": "PHP", "url": "https://hosting-telegram-bota.ru/"}, {"text": "PHP - сила!", "url": "https://hosting-telegram-bota.ru/php-bot/PHP_power.jpg"} ] ] } } r = requests.post(url, json=payload) return r @ app.route('/python-bot/', methods=['GET', 'POST']) def index(): if request.method == 'POST': msg = request.get_json() try: chat_id, txt = tel_parse_message(msg) if txt == "hi": tel_send_message(chat_id,"Hello, world!") elif txt == "/start": tel_send_image(chat_id) elif txt == "/more": tel_send_inlineurl(chat_id) else: tel_send_message(chat_id, 'from webhook') except: print("from index-->") return Response('ok', status=200) else: return '<h1>Это страница-webhook для бота на Python, размещенного на хостинге Beget.</h1>' @app.route('/', defaults={'path': ''}) @app.route('/<path:path>') def catch_all(path): return render_template('home.html') if __name__ == '__main__': app.run(threaded=True)
После сохранения нового кода в init.py – не забываем перезапустить Фласк командой (зайдя на хостинг через SSH):
touch tmp/restart.txt
И также активировать webhook для бота, открыв в браузере:
https://api.telegram.org/bot<токен бота>/setWebhook?url=https://hosting-telegram-bota.ru/python-bot/
Проверяем, открыв страницу бота в браузере, и видим ту надпись, которую мы задали для GET-запроса:
Проверяем как работает сам бот @hosting_telegram_bot
Сервер для телеграмм бота Python
Вот так бот на Python может работать на обычном шаред-хостинге. Бесплатного тестового периода в 30 дней вполне хватит, чтобы поиграться-протестировать гипотезу, запустить MVP.
Конечно, боты бывают разной сложности и замысла. Возможно, все-таки понадобится аренда сервера для бота, которые у Beget
тоже есть с хорошими конфигурациями.
Список с ценами за VPS/VDS – по ссылке.
А здесь короткое видео, как разместить бота на сервере от Бегет:
Недорогие серверы на Beget.
Перезапуск Flask через терминал Beget
Из панели управления хостингом доступен терминал, что позволяет удобно управлять проектом или перезапускать сервер Flask после внесения правок.
Терминал у Бегет находится слева в виде боковой вкладки:
Удобно, что скопировать команды в терминал можно с помощью обычного CTRL+C => CTRL+V. Также (если вы не знакомы с Linux) – стрелками “вверх-вниз” на клавиатуре можно листать историю команд (чтобы не набирать их заново).
При сворачивании терминал сохраняет историю команд, но если что-то зависло или не реагирует – можно закрыть-открыть новую вкладку:
Вот пример, как я перезапускаю Flask после каких-либо правок в теле страницы – например, в данном случае я добавил новую кнопку:
Если я оказался в неправильной директории и команда touch tmp/restart.txt
не сработала – всегда можно посмотреть где мы с помощью команда ls -l
После перехода в папку с сайтом делаем ре-старт Фласка – и теперь все ок. На главной странице добавлена новая кнопка на статью про бота отслеживания подписок на канал:
Полезные ссылки
- Статья на Beget по настройке Python на хостинге
- Код telegram бота на Питоне я подсмотрел здесь
- Кажется, крутой учебник по aiogram
- Еще статья по запуску Flask на Бегете
Бот для сбора статистики – откуда приходят подписчики в канал и для снижения цены привлечения подписчика.