После того как голосовой навык или чат-бот написан и протестирован локально, его нужно развернуть на сервере, чтобы платформы могли отправлять ему запросы. В этом руководстве мы рассмотрим полный цикл деплоя: от получения SSL-сертификата до настройки CI/CD.
acme.sh:curl https://get.acme.sh | sh
acme.sh --issue -d example.com -w /var/www/example
Где:
acme.sh --install-cert -d example.com \
--key-file /etc/ssl/private/example.key \
--fullchain-file /etc/ssl/certs/example.crt \
--reloadcmd "sudo systemctl reload nginx"
Добавьте в конфигурацию nginx:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.crt;
ssl_certificate_key /etc/ssl/private/example.key;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
Перезагрузите nginx:
sudo systemctl reload nginx
Соберите проект:
npm run build
Запустите с помощью pm2 (рекомендуется для продакшена). Если pm2 не установлен, установите его:
npm install -g pm2
Запустите сам процесс:
pm2 start dist/index.js --name "umbot-production"
Для того чтобы после перезагрузки сервера приложение было доступно, выполните следующие команды:
pm2 startup
pm2 save
Теперь ваш навык доступен по HTTPS и готов к подключению в консолях разработчика:
bot.start('0.0.0.0', 3000);
Смотри раздел: Универсальный webhook-обработчик в руководстве по платформам.
При создании проекта через CLI с флагом --prod генерируется готовый Dockerfile.
Соберите образ и запустите контейнер, передав токены через переменные окружения:
docker build -t my-bot .
docker run -p 3000:3000 -e ALISA_TOKEN=... -e TELEGRAM_TOKEN=... my-bot
Если env в конфиге не настроен, фреймворк тихо подтянет известные переменные (TELEGRAM_TOKEN,
ALISA_TOKEN, VK_TOKEN, ...) из окружения контейнера и дозаполнит ими токены — явно писать
env: 'local' для этого не нужно. Если же env: 'local' указан, значения из окружения
перезаписывают заданные токены.
Шаблон .github/workflows/deploy.yml автоматически настраивает:
🔐 Безопасность: никогда не коммитьте .env в Git. Используйте GitHub Secrets.
Для платформ без постоянного сервера (Алиса, Маруся, SmartApp) можно использовать serverless-функции.
При создании проекта через CLI можно автоматически сгенерировать конфигурацию для Yandex Cloud Functions:
npx umbot create from-flow flow.json --usecloud
Это добавит в проект:
handler в src/index.ts для обработки запросов Cloud Functionsscripts/deploy.js — деплой через yc CLI (запускается npm run deploy)serverless.yml с конфигурацией функции (деплой его не читает — аргументы для yc собирает scripts/deploy.js)deploy и build в package.jsonРучная настройка Cloud Function:
import { Bot } from 'umbot';
import { fullPlatforms } from 'umbot/plugins';
const bot = new Bot();
bot.use(fullPlatforms);
bot.setAppConfig({ isLocalStorage: true });
// Экспорт функции для Яндекс Cloud Functions
export const handler = async (event: Record<string, unknown>) => {
const content = typeof event.body === 'string' ? event.body : JSON.stringify(event.body ?? '');
const headers = (event.headers ?? {}) as Record<string, unknown>;
const result = await bot.webhookEvent(content, headers);
return {
statusCode: result.statusCode,
headers: { 'Content-Type': 'application/json' },
body: typeof result.body === 'string' ? result.body : JSON.stringify(result.body ?? ''),
};
};
webhookEvent() — специальный метод для serverless-окружений: в отличие от run(), он сам
определяет платформу по содержимому, проверяет подпись webhook (isCorrectQuery) и возвращает
готовый HTTP-ответ { statusCode, body }. Именно этот код использует генератор from-flow --usecloud.
В serverless
isLocalStorage: trueнадёжно хранит данные только на Алисе, Марусе и SmartApp (состояние приходит в запросе). На Telegram/VK/MAX/Viber без DB-адаптераuserDataживёт в памяти экземпляра функции и теряется, когда вызов попадает в новый экземпляр, — для шагов диалога на чат-платформах подключите БД (например,MongoAdapter).
Подробнее о serverless — в разделе Рецепты: Serverless.
Перед запуском в продакшене убедитесь:
npm run build без ошибокnpm run test зелёныйstrict_prod — bot.setAppMode('strict_prod')bot.setAppConfig({ error_log: './logs' })bot.use(rateLimiter())