Хостинг: Fly
У цьому посібнику ви дізнаєтеся про способи розміщення ваших ботів grammY на Fly, використовуючи Deno або Node.js.
Підготовка коду
Ви можете запустити свого бота, використовуючи вебхуки або тривале опитування.
Вебхуки
Памʼятайте, що ви не повинні викликати
botу своєму коді, коли використовуєте вебхуки..start()
- Переконайтеся, що у вас є файл, який експортує ваш обʼєкт
Bot, щоб ви могли імпортувати його пізніше для запуску. - Створіть файл з назвою
appабо.ts appабо насправді будь-якою назвою, яку ви хочете, але ви повинні памʼятати і використовувати його як головний файл для розгортання, з наступним вмістом:.js
import { webhookCallback } from "https://deno.land/x/grammy@v1.38.3/mod.ts";
// Ви можете змінити це на правильний спосіб імпорту вашого обʼєкта `Bot`.
import { bot } from "./bot.ts";
const port = 8000;
const handleUpdate = webhookCallback(bot, "std/http");
Deno.serve({ port }, async (req) => {
const url = new URL(req.url);
if (req.method === "POST" && url.pathname.slice(1) === bot.token) {
try {
return await handleUpdate(req);
} catch (err) {
console.error(err);
}
}
return new Response();
});2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import express from "express";
import { webhookCallback } from "grammy";
// Ви можете змінити це на правильний спосіб імпорту вашого обʼєкта `Bot`.
import { bot } from "./bot";
const port = 8000;
const app = express();
app.use(express.json());
app.use(`/${bot.token}`, webhookCallback(bot, "express"));
app.use((_req, res) => res.status(200).send());
app.listen(port, () => console.log(`працюю на порті ${port}`));2
3
4
5
6
7
8
9
10
11
12
13
Ми радимо вам зареєструвати ваш обробник на деякому секретному шляху, а не на кореневому (/). Як показано на підсвіченому рядку вище, ми використовуємо токен бота (/<токен бота>) як секретний шлях.
Тривале опитування
Створіть файл з назвою app або app або насправді будь-якою назвою, яку ви хочете, але ви повинні памʼятати і використовувати його як головний файл для розгортання, з наступним вмістом:
import { Bot } from "https://deno.land/x/grammy@v1.38.3/mod.ts";
const token = Deno.env.get("BOT_TOKEN");
if (!token) throw new Error("BOT_TOKEN не вказано");
const bot = new Bot(token);
bot.command(
"start",
(ctx) => ctx.reply("Я запущений на Fly за допомогою тривалого опитування!"),
);
Deno.addSignalListener("SIGINT", () => bot.stop());
Deno.addSignalListener("SIGTERM", () => bot.stop());
bot.start();2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { Bot } from "grammy";
const token = process.env.BOT_TOKEN;
if (!token) throw new Error("BOT_TOKEN не вказано");
const bot = new Bot(token);
bot.command(
"start",
(ctx) => ctx.reply("Я запущений на Fly за допомогою тривалого опитування!"),
);
process.once("SIGINT", () => bot.stop());
process.once("SIGTERM", () => bot.stop());
bot.start();2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Як ви можете побачити на підсвіченому рядку вище, ми отримуємо деякі конфіденційні значення (токен вашого бота) зі змінних середовища. Fly дозволяє нам зберігати цей секрет, виконавши цю команду:
flyctl secrets set BOT_TOKEN="AAAA:12345"Ви можете вказати інші секрети аналогічним чином. Для отримання додаткової інформації про ці секрети, дивіться https://
Розгортання
1-й метод: за допомогою flyctl
Цей метод є найпростішим для використання.
Встановіть flyctl та авторизуйтесь.
Виконайте команду
flyctl launch, щоб згенерувати файлиDockerfileтаflyдля розгортання. Але НЕ розгортайте ваш проєкт..toml shflyctl launch1logCreating app in /my/telegram/bot Scanning source code Detected a Deno app ? App Name (leave blank to use an auto-generated name): grammy Automatically selected personal organization: CatDestroyer ? Select region: ams (Amsterdam, Netherlands) Created app grammy in organization personal Wrote config file fly.toml ? Would you like to set up a Postgresql database now? No ? Would you like to deploy now? No Your app is ready. Deploy with `flyctl deploy`1
2
3
4
5
6
7
8
9
10
11shflyctl launch1logCreating app in /my/telegram/bot Scanning source code Detected a NodeJS app Using the following build configuration: Builder: heroku/buildpacks:20 ? App Name (leave blank to use an auto-generated name): grammy Automatically selected personal organization: CatDestroyer ? Select region: ams (Amsterdam, Netherlands) Created app grammy in organization personal Wrote config file fly.toml ? Would you like to set up a Postgresql database now? No ? Would you like to deploy now? No Your app is ready. Deploy with `flyctl deploy`1
2
3
4
5
6
7
8
9
10
11
12
13Deno: змініть версію Deno та видаліть
CMD, якщо він існує, у файліDockerfile. Наприклад, у цьому випадку ми оновлюємоDENOдо_VERSION 1..25 .2 Node.js: щоб змінити версію Node.js, вам потрібно вставити властивість
"node"в межах властивості"engines"уpackage. Ми оновлюємо версію Node.js до.json 16у наступному прикладі..14 .0 dockerfile# Dockerfile ARG DENO_VERSION=1.25.2 ARG BIN_IMAGE=denoland/deno:bin-${DENO_VERSION} FROM ${BIN_IMAGE} AS bin FROM frolvlad/alpine-glibc:alpine-3.13 RUN apk --no-cache add ca-certificates RUN addgroup --gid 1000 deno \ && adduser --uid 1000 --disabled-password deno --ingroup deno \ && mkdir /deno-dir/ \ && chown deno:deno /deno-dir/ ENV DENO_DIR /deno-dir/ ENV DENO_INSTALL_ROOT /usr/local ARG DENO_VERSION ENV DENO_VERSION=${DENO_VERSION} COPY --from=bin /deno /bin/deno WORKDIR /deno-dir COPY . . ENTRYPOINT ["/bin/deno"] # CMD видалено1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26json// package.json { "name": "grammy", "version": "1.0.0", "description": "grammy", "main": "app.js", "author": "itsmeMario", "license": "MIT", "dependencies": { "express": "^4.18.1", "grammy": "^1.11.0" }, "devDependencies": { "@types/express": "^4.17.14", "@types/node": "^18.7.18", "typescript": "^4.8.3" }, "engines": { "node": "16.14.0" } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21Відредагуйте
appу файліfly. Шлях.toml .або/app .ts .для Node.js у наведеному нижче прикладі вказує на розташування головного файлу. Ви можете змінити їх, щоб вони відповідали каталогу вашого проєкту. Якщо ви використовуєте вебхуки, переконайтеся, що порт відповідає тому, що ви вказали у своєму конфігураційному файлі (/app .js 8000).toml# fly.toml app = "grammy" kill_signal = "SIGINT" kill_timeout = 5 [processes] app = "run --allow-net ./app.ts" [[services]] http_checks = [] internal_port = 8000 processes = ["app"] protocol = "tcp" script_checks = [] [services.concurrency] hard_limit = 25 soft_limit = 20 type = "connections" [[services.ports]] force_https = true handlers = ["http"] port = 80 [[services.ports]] handlers = ["tls", "http"] port = 443 [[services.tcp_checks]] grace_period = "1s" interval = "15s" restart_limit = 0 timeout = "2s"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33toml# fly.toml app = "grammy" kill_signal = "SIGINT" kill_timeout = 5 [processes] app = "run --allow-net ./app.ts" # Просто опускаємо весь розділ [[services]], # оскільки ми не прослуховуємо HTTP1
2
3
4
5
6
7
8
9
10toml# fly.toml app = "grammy" kill_signal = "SIGINT" kill_timeout = 5 [processes] app = "node ./build/app.js" # Налаштуйте змінну середовища NODE_ENV, щоб прибрати попередження. [build.args] NODE_ENV = "production" [build] builder = "heroku/buildpacks:20" [[services]] http_checks = [] internal_port = 8000 processes = ["app"] protocol = "tcp" script_checks = [] [services.concurrency] hard_limit = 25 soft_limit = 20 type = "connections" [[services.ports]] force_https = true handlers = ["http"] port = 80 [[services.ports]] handlers = ["tls", "http"] port = 443 [[services.tcp_checks]] grace_period = "1s" interval = "15s" restart_limit = 0 timeout = "2s"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40toml# fly.toml app = "grammy" kill_signal = "SIGINT" kill_timeout = 5 [processes] app = "node ./build/app.js" # Налаштуйте змінну середовища NODE_ENV, щоб прибрати попередження. [build.args] NODE_ENV = "production" [build] builder = "heroku/buildpacks:20" # Просто пропустіть увесь розділ [[services]], оскільки ми не прослуховуємо HTTP.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16Запустіть
flyctl deployдля розгортання вашого коду.
2-й метод: за допомогою GitHub Actions
Основною перевагою такого підходу є те, що Fly буде стежити за змінами у вашому репозиторії, включаючи код вашого бота, й автоматично розгортатиме нові версії. Відвідайте https://
Встановіть flyctl та авторизуйтесь.
Отримайте токен Fly API, виконавши
flyctl auth token.Створіть репозиторій на GitHub, який може бути приватним або загальнодоступним.
Перейдіть до налаштувань, виберіть вкладку секретів та створіть секрет з назвою
FLYта значенням токена з 2-го кроку._API _TOKEN Створіть
.githubіз таким змістом:/workflows /main .yml ymlname: Розгортання на Fly on: [push] env: FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} jobs: deploy: name: Розгортання застосунку runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: superfly/flyctl-actions/setup-flyctl@master - run: flyctl deploy --remote-only1
2
3
4
5
6
7
8
9
10
11
12Виконайте 2-й та 4-й крок з 1
-го методу вище.
Зверніть увагу, що останній, 5-й, крок потрібно пропустити, оскільки ми не розгортаємо код вручну. 7. Збережіть внесені зміни і відправте їх на GitHub. 8. Ось тут і відбувається чаклунство — push викликав розгортання, і з цього моменту, кожного разу, коли ви зробите зміну і відправите її на GitHub, додаток автоматично буде розгоратися.
Налаштування URL-адреси вебхуку
Якщо ви використовуєте вебхуки, після запуску вашого застосунку, вам потрібно налаштувати вебхук вашого бота, щоб запити посилалися на ваш застосунок. Для цього відправте запит на
https://api.telegram.org/bot<токен-бота>/setWebhook?url=<адреса>замініть <токен на токен вашого бота, а <адреса> — на повну URL-адресу вашого застосунку разом з шляхом до обробника вебхуку.
Оптимізація Dockerfile
При запуску Dockerfile він копіює все з каталогу в образ Docker. Для застосунків Node.js деякі каталоги, як-от node, все одно будуть перебудовані, тому немає необхідності їх копіювати. Для цього створіть файл .dockerignore і додайте до нього node. Ви також можете використовувати .dockerignore, щоб не копіювати будь-які інші файли, які не потрібні під час виконання.