{"id":349305,"date":"2023-06-24T21:01:15","date_gmt":"2023-06-24T21:01:15","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=349305"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=349305","title":{"rendered":"<span>\u041a\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c full-stack \u0441 \u043e\u0434\u043d\u043e\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0431\u0435\u0437 \u0421\u041c\u0421 \u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0434\u043b\u044f \u043b\u0430\u043c\u0435\u0440\u043e\u0432<\/h3>\n<p>\u042f \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e \u0443\u0447\u0438\u043b\u0441\u044f \u043a\u043e\u0434\u0438\u0442\u044c, \u0438 \u0432\u0434\u0440\u0443\u0433 \u0437\u0430\u043c\u0435\u0442\u0438\u043b \u0447\u0442\u043e \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u043b \u0432\u0435\u0431 \u0430\u043f\u0438 \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0444\u0440\u043e\u043d\u0442&#8230;<\/p>\n<p>\u041d\u0430 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u044f \u0443\u0436\u0435 \u0432\u043b\u0430\u0434\u0435\u043b React, Flask \u0438 Django, \u0438 \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u043f\u043b\u0430\u043d\u043a\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e FastAPI.<\/p>\n<p>\u0412\u0435\u0440\u044f \u0432 \u0441\u0432\u043e\u0438 \u0441\u0438\u043b\u044b, \u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b FastAPI \u0438 aiogram. \u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u043c\u043d\u0435 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u043e \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b Telegram API, \u043d\u043e aiogram \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0443\u0434\u043e\u0431\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0441\u043a\u043e\u0440\u044f\u044e\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443.<\/p>\n<h3>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/h3>\n<p>Django \u0438 Flask \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u044b (\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b Jinja2), \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043a\u043e\u0434, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 (HTML, JS, CSS, TS \u0438 \u0442. \u0434.), \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0443 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043b\u044f \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434\u0430.<\/p>\n<p>\u043e\u0434\u043d\u0430\u043a\u043e Fast-api \u0438 React, \u043d\u0443\u0436\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u0445 &#8230;<\/p>\n<p>\u042f \u043f\u043e\u043d\u0438\u043c\u0430\u044e, \u0447\u0442\u043e \u043d\u0430\u0439\u0434\u0443\u0442\u0441\u044f \u043b\u044e\u0434\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043a\u0430\u0436\u0443\u0442: &#171;\u0417\u0430\u0447\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043b\u044f React, \u0435\u0441\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Knockout.js \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435?&#187; &#8212; \u0414\u0430, \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043d\u043e \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438, \u0430 \u043d\u0435 \u043a\u043e\u0441\u0442\u044b\u043b\u0438 \u043d\u0430 \u043a\u043e\u0441\u0442\u044b\u043b\u044f\u0445, \u0447\u0442\u043e\u0431\u044b \u043a \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0443 \u0432\u0430\u0441 \u0431\u044b\u043b \u0446\u0435\u043d\u043d\u044b\u0439 \u043e\u043f\u044b\u0442 \u0432 \u0440\u0435\u0437\u044e\u043c\u0435, \u0430 \u043d\u0435 \u043f\u043e\u0432\u043e\u0434 \u0434\u043b\u044f \u043f\u0435\u043d\u0441\u0438\u0438))<\/p>\n<p>\u042f \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0441\u044f \u0441 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0435\u0433\u043e Knockout,js \u0438 Python 2, \u0432\u0441\u0435 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0435. \u0421\u0445\u0435\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043a \u0442\u043e\u043c\u0443 \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u0434\u0436\u0443\u043d\u043e\u0432 \u0438 \u043f\u043b\u0430\u0442\u0438\u0442\u044c \u0438\u043c \u043c\u0435\u043d\u044c\u0448\u0435, \u0432\u0435\u0434\u044c \u0432\u0441\u0435\u0445 \u043e\u0431\u0443\u0447\u0430\u044e\u0442 Django \u043d\u0430 \u043a\u0443\u0440\u0441\u0430\u0445).<\/p>\n<h3>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 <\/h3>\n<p>\u0412\u043e\u0442 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 &#8212; FastAPI \u0438 React. \u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0445 \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0441 Telegram API. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0430\u043a\u043e\u0439 \u0441\u0432\u044f\u0437\u0438: \u0440\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, FastAPI \u0438 Telegram \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0447\u0435\u0440\u0435\u0437 webhook. \u0427\u0442\u043e\u0431\u044b \u0438\u0445 \u0441\u0432\u0435\u0441\u0442\u0438 \u0432\u043c\u0435\u0441\u0442\u0435, \u043c\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441 Telegram \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043e\u0442 ngrok, \u0438 \u0442\u043e\u043a\u0435\u043d \u0431\u043e\u0442\u0430 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 .env. \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0430\u0434\u0440\u0435\u0441 ngrok \u0432 .env, \u0438 FastAPI \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0441\u0432\u044f\u0437\u044c \u0441 Telegram \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e ngrok, \u0434\u0430\u0436\u0435 \u0432 \u043f\u043b\u0430\u0442\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0430\u0434\u0440\u0435\u0441, \u0430 \u0443 \u043c\u0435\u043d\u044f \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u0442\u0443. \u041e\u0434\u043d\u0430\u043a\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 localhost.run. \u041e\u043d\u0430 \u0438\u043c\u0435\u0435\u0442 \u0441\u0445\u043e\u0436\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0441 ngrok, \u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0447\u0443\u0442\u043a\u0430 \u0441\u043b\u043e\u0436\u043d\u0435\u0435.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u043b\u0430\u043d \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f \u0431\u044b \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u043b\u0441\u044f <\/p>\n<ol>\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c localhost.run \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 3000 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0431\u044d\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c React \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 3000<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c ngrok \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 8000 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c Fast-api \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 8000<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043b\u0430\u043d \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439, \u043a\u0430\u043a \u0448\u0432\u0435\u0439\u0446\u0430\u0440\u0441\u043a\u0438\u0435 \u0447\u0430\u0441\u044b. <\/p>\n<h3>1. localhost.run <\/h3>\n<p>\u0417\u0430\u0445\u043e\u0434\u0438\u043c \u043d\u0430 <a href=\"https:\/\/admin.localhost.run\/\" rel=\"noopener noreferrer nofollow\">https:\/\/admin.localhost.run\/<\/a> \u0440\u0435\u0433\u0430\u0435\u043c\u0441\u044f\\\u043b\u043e\u0433\u0438\u043d\u0438\u043c\u0441\u044f. <\/p>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c shh \u043a\u043b\u044e\u0447  <a href=\"https:\/\/docs.gitlab.com\/ee\/user\/ssh.html#rsa-ssh-keys\" rel=\"noopener noreferrer nofollow\">\u043e\u0440\u0438\u0433.  \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0441\u0441\u043a\u043e\u043c<\/a>. \u041a\u043b\u044e\u0447 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 2\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0439 \u0438 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0439. \u0437\u0430\u0445\u043e\u0434\u0438\u043c \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u0438 \u043f\u0438\u0448\u0435\u043c <\/p>\n<pre><code>ssh-keygen -t rsa -b 2048 -C \"&lt;comment>\"<\/code><\/pre>\n<p>*\u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0435\u043c\u0435\u0439\u043b<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/eaa\/9ec\/74a\/eaa9ec74a9736bc89736d50568b65289.png\" alt=\"\u044d\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u0430\u043a \u043e\u0442\u0432\u0435\u0442\" title=\"\u044d\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u0430\u043a \u043e\u0442\u0432\u0435\u0442\" width=\"1264\" height=\"198\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/eaa\/9ec\/74a\/eaa9ec74a9736bc89736d50568b65289.png\"\/><\/p>\n<div><figcaption>\u044d\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u0430\u043a \u043e\u0442\u0432\u0435\u0442<\/figcaption><\/div>\n<\/figure>\n<p>\u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043b\u044e\u0447\u0430. \u0438 \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u043f\u0443\u0442\u044c. \u0435\u0441\u043b\u0438 \u043d\u0435 \u0432\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u043c\u044f \u0442\u043e \u043a\u043b\u044e\u0447\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0441 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u043c\u0438 \u0438\u043c\u0435\u043d\u0430\u043c\u0438 id_rsa \u0438 id_rsa.pub<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/984\/bb5\/9b5\/984bb59b5d6eca5f2409e538da6e8be8.png\" alt=\"\u0436\u043c\u0435\u043c \u0435\u043d\u0442\u0435\u0440 , \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0447\u0442\u043e \u043a\u043b\u044e\u0447 \u0433\u043e\u0442\u043e\u0432. \" title=\"\u0436\u043c\u0435\u043c \u0435\u043d\u0442\u0435\u0440 , \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0447\u0442\u043e \u043a\u043b\u044e\u0447 \u0433\u043e\u0442\u043e\u0432. \" width=\"1332\" height=\"294\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/984\/bb5\/9b5\/984bb59b5d6eca5f2409e538da6e8be8.png\"\/><\/p>\n<div><figcaption>\u0436\u043c\u0435\u043c \u0435\u043d\u0442\u0435\u0440 , \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0447\u0442\u043e \u043a\u043b\u044e\u0447 \u0433\u043e\u0442\u043e\u0432. <\/figcaption><\/div>\n<\/figure>\n<p>\u0438\u0434\u0435\u043c \u0432  \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u043a\u043b\u044e\u0447\u0430, \u0436\u043c\u0435\u043c ls -1 \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0447\u0442\u043e \u043f\u0440\u0438\u0448\u043b\u0438 \u0432 \u043d\u0443\u0436\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u0438 \u043a\u043b\u044e\u0447\u0438 \u0433\u043e\u0442\u043e\u0432\u044b \u0438 \u0436\u0434\u0443\u0442 \u043d\u0430\u0441. <\/p>\n<pre><code>ls -1<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/56f\/46c\/af5\/56f46caf54fe18e59c1ee7b68c6932af.png\" alt=\"\u043a\u0430\u043a \u044f \u043f\u043e\u043d\u044f\u043b  \u0432 \u043f\u0430\u043f\u043a\u0443 .ssh \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u043f\u043e\u043f\u0430\u0441\u0442\u044c  \" title=\"\u043a\u0430\u043a \u044f \u043f\u043e\u043d\u044f\u043b  \u0432 \u043f\u0430\u043f\u043a\u0443 .ssh \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u043f\u043e\u043f\u0430\u0441\u0442\u044c  \" width=\"1402\" height=\"166\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/56f\/46c\/af5\/56f46caf54fe18e59c1ee7b68c6932af.png\"\/><\/p>\n<div><figcaption>\u043a\u0430\u043a \u044f \u043f\u043e\u043d\u044f\u043b  \u0432 \u043f\u0430\u043f\u043a\u0443 .ssh \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u043f\u043e\u043f\u0430\u0441\u0442\u044c  <\/figcaption><\/div>\n<\/figure>\n<p>id_rsa \u0438 id_rsa.pub \u044d\u0442\u043e \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u0438 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u043a\u043b\u044e\u0447\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0432\u0435\u043d\u043d\u043e. \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c id_rsa.pub  \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e vim \u0438\u043b\u0438 nano. \u0415\u0441\u043b\u0438 \u043d\u0435\u0442 vim \u0442\u043e \u0441\u0442\u0430vim vim))<\/p>\n<pre><code>vim id_rsa.pub<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6e2\/1b0\/704\/6e21b07048f0934ca806e0df747d7eb8.png\" width=\"1314\" height=\"862\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6e2\/1b0\/704\/6e21b07048f0934ca806e0df747d7eb8.png\"\/><\/figure>\n<p>\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438(\u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 shh \u0438 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 \u0442\u0435\u043a\u0441\u0442\u0430)<br \/>\u0434\u0430\u043b\u044c\u0448\u0435 \u0432\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u0432\u0438\u043c\u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0436\u043c\u0435\u043c \u201c:\u201d \u0438 \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u043c q! \u0438 \u0436\u043c\u0435\u043c \u0435\u043d\u0442\u044b\u0440. <\/p>\n<p>\u0438\u0434\u0435\u043c \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u043d\u0430 <a href=\"https:\/\/admin.localhost.run\/#\/keys\" rel=\"noopener noreferrer nofollow\">https:\/\/admin.localhost.run\/#\/keys<\/a> \u0432\u0432\u043e\u0434\u0438\u043c \u0442\u0430\u043c \u044d\u0442\u043e\u0442 \u043a\u043b\u044e\u0447<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/20f\/d16\/a08\/20fd16a0825d720082a840cd249846bf.png\" alt=\"\u0436\u043c\u0435\u043c \u0441\u0430\u0431\u043c\u0438\u0442\" title=\"\u0436\u043c\u0435\u043c \u0441\u0430\u0431\u043c\u0438\u0442\" width=\"1358\" height=\"768\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/20f\/d16\/a08\/20fd16a0825d720082a840cd249846bf.png\"\/><\/p>\n<div><figcaption>\u0436\u043c\u0435\u043c \u0441\u0430\u0431\u043c\u0438\u0442<\/figcaption><\/div>\n<\/figure>\n<p>\u0434\u0430\u043b\u044c\u0448\u0435 \u0438\u0434\u0435\u043c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c<\/p>\n<pre><code>ssh -R 80:localhost:3000 localhost.run<\/code><\/pre>\n<p>\u0427\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0435\u0442 \u044d\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 <a href=\"https:\/\/localhost.run\/docs\/\" rel=\"noopener noreferrer nofollow\">\u043c\u043e\u0436\u043d\u043e\u043f\u043e\u0447\u0442\u0438\u0442\u0430\u0442\u044c \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/a><\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0430\u0448 \u0431\u0435\u043b\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 3000<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6ff\/36a\/537\/6ff36a53714d52e106b0979c3a3b17fe.png\" alt=\"\u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0435 \u043f\u043e\u0440\u0442 3003 \u0430 \u043d\u0435 3000\" title=\"\u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0435 \u043f\u043e\u0440\u0442 3003 \u0430 \u043d\u0435 3000\" width=\"1344\" height=\"694\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6ff\/36a\/537\/6ff36a53714d52e106b0979c3a3b17fe.png\"\/><\/p>\n<div><figcaption>\u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0435 \u043f\u043e\u0440\u0442 3003 \u0430 \u043d\u0435 3000<\/figcaption><\/div>\n<\/figure>\n<p>\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u0432 .env \u0431\u044d\u043a\u0430 <\/p>\n<p>\u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0441\u0442\u0430\u043b\u043e \u0432\u0440\u0435\u043c\u044f REACT<\/p>\n<h3>2. REACT<\/h3>\n<p>\u0418\u0442\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0431\u0435\u0437 \u0442\u0430\u043d\u0446\u0435\u0432,<a href=\"https:\/\/github.com\/dandaniel5\/newReactCompose\/tree\/main\" rel=\"noopener noreferrer nofollow\"> \u044f \u0441\u0434\u0435\u043b\u044f\u043b\u044c \u0432\u0438\u0437\u0437\u0430\u0440\u0434 \u0441\u043a\u0440\u0438\u043f\u0442<\/a>. \u041e\u0442\u043c\u0435\u0447\u0443 \u0447\u0442\u043e \u043e\u043d \u0434\u0430\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u0442\u044c js\/jsx, yarn\/npm, \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0434\u043e\u043a\u0435\u0440 \u0438 \u0434\u043e\u043a\u0435\u0440 \u043a\u043e\u043c\u043f\u043e\u0443\u0437 \u0441 \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044b\u043c\u0438 \u043f\u043e\u0440\u0442\u0430\u043c\u0438, \u0430 \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u0432\u044b\u043d\u0435\u0441\u0435\u043d \u0432 \u0432\u0430\u043b\u0438\u0443\u043c \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u0441\u0431\u043e\u0440\u043a\u0438. <\/p>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043e\u0437\u0434\u0430\u0435\u043c create_react_compose_app.sh \u0438\u043b\u0438 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0441 <a href=\"https:\/\/github.com\/dandaniel5\/newReactCompose\/blob\/main\/create_react_copmpose_app.sh\" rel=\"noopener noreferrer nofollow\">github<\/a>.<\/p>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u043c , \u043d\u0430 \u043c\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>chmod +x create_react_compose_app.sh<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0441\u043a\u0440\u0438\u043f\u0442:<\/p>\n<pre><code>bash create_react_copmpose_app.sh<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/955\/a6f\/db4\/955a6fdb4ca9870ea5109073917d200b.png\" alt=\"\u0434\u0430\u043b\u044c\u0448\u0435 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u0432\u0441\u0435 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0442\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0449\u0435\u043b\u043a\u0430\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b. \u0438\u043c\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u044d\u0442\u043e pwd + web re , npm , js\" title=\"\u0434\u0430\u043b\u044c\u0448\u0435 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u0432\u0441\u0435 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0442\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0449\u0435\u043b\u043a\u0430\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b. \u0438\u043c\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u044d\u0442\u043e pwd + web re , npm , js\" width=\"1860\" height=\"524\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/955\/a6f\/db4\/955a6fdb4ca9870ea5109073917d200b.png\"\/><\/p>\n<div><figcaption>\u0434\u0430\u043b\u044c\u0448\u0435 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u0432\u0441\u0435 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0442\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0449\u0435\u043b\u043a\u0430\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b. \u0438\u043c\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u044d\u0442\u043e pwd + web re , npm , js<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8f3\/86b\/847\/8f386b8478986f4da71b72ebea705255.png\" alt=\"\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0434\u043e\u043a\u0435\u0440\u0444\u0430\u0438\u043b \" title=\"\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0434\u043e\u043a\u0435\u0440\u0444\u0430\u0438\u043b \" width=\"630\" height=\"372\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8f3\/86b\/847\/8f386b8478986f4da71b72ebea705255.png\"\/><\/p>\n<div><figcaption>\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0434\u043e\u043a\u0435\u0440\u0444\u0430\u0438\u043b <\/figcaption><\/div>\n<\/figure>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0434\u043e\u043a\u0435\u0440, \u043f\u043e\u0441\u043b\u0435 \u0432\u0432\u043e\u0434\u0438\u043c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c <\/p>\n<pre><code>docker-compose up<\/code><\/pre>\n<p>\u0418 \u0432\u043e\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u043e \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 3000, \u0442\u0435\u043f\u0435\u0440\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0438\u0434\u0435\u043c \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432 localhost.run<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d6b\/623\/8d2\/d6b6238d2ad9e3db509cc4d09b06c4c7.png\" alt=\"\u0438 \u0432\u043e\u0442 \u043c\u044b \u043e\u043d\u043b\u0430\u0439\u043d\" title=\"\u0438 \u0432\u043e\u0442 \u043c\u044b \u043e\u043d\u043b\u0430\u0439\u043d\" width=\"1700\" height=\"1328\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d6b\/623\/8d2\/d6b6238d2ad9e3db509cc4d09b06c4c7.png\"\/><\/p>\n<div><figcaption>\u0438 \u0432\u043e\u0442 \u043c\u044b \u043e\u043d\u043b\u0430\u0439\u043d<\/figcaption><\/div>\n<\/figure>\n<p>\u0418\u0434\u0435\u043c \u0432 <\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/05b\/dc5\/b29\/05bdc5b29975b48bb12abcc07222ed1d.png\" alt=\"\u0438\u0434\u0435\u043c \u0432 \" title=\"\u0438\u0434\u0435\u043c \u0432 \" width=\"368\" height=\"416\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/05b\/dc5\/b29\/05bdc5b29975b48bb12abcc07222ed1d.png\"\/><\/p>\n<div><figcaption>\u0438\u0434\u0435\u043c \u0432 <\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c index.html \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0443\u0434\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c <\/p>\n<pre><code>&lt;script src=\"https:\/\/telegram.org\/js\/telegram-web-app.js\">&lt;\/script><\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/88c\/8d1\/3de\/88c8d13de8f2420defdb02a9d49a2e99.png\" alt=\"\u043f\u0440\u044f\u043c\u043e \u0432 head\" title=\"\u043f\u0440\u044f\u043c\u043e \u0432 head\" width=\"1310\" height=\"252\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/88c\/8d1\/3de\/88c8d13de8f2420defdb02a9d49a2e99.png\"\/><\/p>\n<div><figcaption>\u043f\u0440\u044f\u043c\u043e \u0432 head<\/figcaption><\/div>\n<\/figure>\n<p>\u0418 \u0437\u0430\u043c\u0435\u043d\u0438\u043c  <\/p>\n<pre><code>&lt;p>  Edit &lt;code>src\/App.js&lt;\/code> and save to reload.&lt;\/p>   &lt;a           className=\"App-link\"           href=\"https:\/\/reactjs.org\"           target=\"_blank\"           rel=\"noopener noreferrer\"         >           Learn React         &lt;\/a><\/code><\/pre>\n<p>\u041d\u0430 <\/p>\n<pre><code>&lt;p> Hellow Habr. &lt;\/p><\/code><\/pre>\n<p>\u0412 src\/App.js<\/p>\n<p>\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u043b localhost.run<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7bf\/56c\/496\/7bf56c4969d3ece665d99e52d23cd0df.png\" alt=\"\u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e\u0432\u0435\u0437\u043b\u043e :)\" title=\"\u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e\u0432\u0435\u0437\u043b\u043e :)\" width=\"638\" height=\"934\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7bf\/56c\/496\/7bf56c4969d3ece665d99e52d23cd0df.png\"\/><\/p>\n<div><figcaption>\u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e\u0432\u0435\u0437\u043b\u043e \ud83d\ude42<\/figcaption><\/div>\n<\/figure>\n<h3>3. Ngrok<\/h3>\n<p>\u0438\u0434\u0435\u043c \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u043d\u0430 <a href=\"https:\/\/ngrok.com\/\" rel=\"noopener noreferrer nofollow\">https:\/\/ngrok.com\/<\/a>  \u0420\u0435\u0433\u0430\u0435\u043c\u0441\u044f\/\u043b\u043e\u0433\u0438\u043d\u0438\u043c\u0441\u044f<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e4b\/b67\/f56\/e4bb67f5638fde0191e47af395c78a3a.png\" alt=\"\u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u044e \u043f\u043e\u0434 \u0441\u0432\u043e\u044e \u043e\u0441 \" title=\"\u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u044e \u043f\u043e\u0434 \u0441\u0432\u043e\u044e \u043e\u0441 \" width=\"894\" height=\"368\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e4b\/b67\/f56\/e4bb67f5638fde0191e47af395c78a3a.png\"\/><\/p>\n<div><figcaption>\u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u044e \u043f\u043e\u0434 \u0441\u0432\u043e\u044e \u043e\u0441 <\/figcaption><\/div>\n<\/figure>\n<p>\u0438\u0434\u0435\u043c \u0432 <a href=\"https:\/\/dashboard.ngrok.com\/get-started\/setup\" rel=\"noopener noreferrer nofollow\">https:\/\/dashboard.ngrok.com\/get-started\/setup<\/a> <\/p>\n<p>\u0434\u0435\u043b\u0430\u043c \u0432\u0441\u0435 \u043f\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p> \u0440\u0430\u0437\u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c zip<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u043b\u044e\u0447 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433, \u0443\u0434\u043e\u0431\u043d\u043e \u0447\u0442\u043e \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0441\u0440\u0430\u0437\u0443 \u0434\u0430\u044e\u0442\u0441\u044f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0441 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u043a\u043b\u044e\u0447\u043e\u043c  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7e8\/d36\/5c3\/7e8d365c3df602c079fe441ded5f8e41.png\" alt=\"\u043d\u0435 \u043d\u0430\u0434\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u044d\u0442\u043e \u0433\u043e\u0442\u043e\u0432\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430. \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u0442\u0443\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e ngrok\" title=\"\u043d\u0435 \u043d\u0430\u0434\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u044d\u0442\u043e \u0433\u043e\u0442\u043e\u0432\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430. \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u0442\u0443\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e ngrok\" width=\"2212\" height=\"384\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7e8\/d36\/5c3\/7e8d365c3df602c079fe441ded5f8e41.png\"\/><\/p>\n<div><figcaption>\u043d\u0435 \u043d\u0430\u0434\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u044d\u0442\u043e \u0433\u043e\u0442\u043e\u0432\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430. \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u0442\u0443\u0442 <a href=\"https:\/\/ngrok.com\/docs\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e ngrok<\/a><\/figcaption><\/div>\n<\/figure>\n<\/li>\n<li>\n<p>\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c ngrok \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 8000<\/p>\n<pre><code>ngrok http 8000<\/code><\/pre>\n<\/li>\n<\/ul>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/597\/051\/37b\/59705137b8c57096fc51836cef384a79.png\" alt=\"\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0442\u043e\u0440\u043e\u0439 \u0431\u0435\u043b\u044b\u0439 \u0430\u043f\u0438 \u0430\u0434\u0440\u0435\u0441\u0441\" title=\"\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0442\u043e\u0440\u043e\u0439 \u0431\u0435\u043b\u044b\u0439 \u0430\u043f\u0438 \u0430\u0434\u0440\u0435\u0441\u0441\" width=\"2104\" height=\"1493\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/597\/051\/37b\/59705137b8c57096fc51836cef384a79.png\"\/><\/p>\n<div><figcaption>\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0442\u043e\u0440\u043e\u0439 \u0431\u0435\u043b\u044b\u0439 \u0430\u043f\u0438 \u0430\u0434\u0440\u0435\u0441\u0441<\/figcaption><\/div>\n<\/figure>\n<h3>4. Fast-API<\/h3>\n<p>\u0437\u0430\u0445\u043e\u0434\u0438\u043c \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/737\/226\/54a\/73722654a7b32bc8da033f2dc4c2d943.png\" alt=\"\u0437\u0430\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0441\u0442\u0440\u0435\u043b\u043a\u0435 \" title=\"\u0437\u0430\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0441\u0442\u0440\u0435\u043b\u043a\u0435 \" width=\"1486\" height=\"437\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/737\/226\/54a\/73722654a7b32bc8da033f2dc4c2d943.png\"\/><\/p>\n<div><figcaption>\u0437\u0430\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0441\u0442\u0440\u0435\u043b\u043a\u0435 <\/figcaption><\/div>\n<\/figure>\n<p>\u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0430\u043f\u043a\u0443 Fast-API \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0443<\/p>\n<pre><code>mkdir Fast-API<\/code><\/pre>\n<p>\u043f\u0435\u0440\u0435\u0434\u0435\u043c \u0432 \u043d\u0435\u0435 <\/p>\n<pre><code>cd Fast-API<\/code><\/pre>\n<p>\u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c <a href=\"http:\/\/main.py\" rel=\"noopener noreferrer nofollow\">main.py<\/a> \u0438 <a href=\"http:\/\/README.md\" rel=\"noopener noreferrer nofollow\">README.md<\/a>, .env c \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0436\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b  touch. \u041b\u0435\u0433\u043a\u043e \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043f\u0440\u043e \u043d\u0435 \u0435\u0441\u0442\u044c \u043f\u0435\u0441\u043d\u044f \u0443 <a href=\"https:\/\/www.youtube.com\/watch?v=0Gkhol2Q1og\" rel=\"noopener noreferrer nofollow\"><strong>Daft Punk &#8212; Touch<\/strong><\/a><strong> <\/strong><\/p>\n<p> \u0441\u043e\u0437\u0434\u0430\u0435\u043c  \u0444\u0430\u0438\u043b \u0438 \u043a\u043b\u0430\u0434\u0435\u043c \u0442\u0443\u0434\u0430 \u0430\u0434\u0440\u0435\u0441 \u0438\u0437 localhost.run , ngrok , \u0442\u043e\u043a\u0435\u043d\u0431\u043e\u0442\u0430 &#8230;<\/p>\n<pre><code>touch .env<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/324\/0aa\/7ec\/3240aa7ece2d01d7ac870c4c32fbb4eb.png\" alt=\"\u0432\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u0434\u043b\u044f .env \u0444\u0430\u0439\u043b\u0430\" title=\"\u0432\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u0434\u043b\u044f .env \u0444\u0430\u0439\u043b\u0430\" width=\"1164\" height=\"104\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/324\/0aa\/7ec\/3240aa7ece2d01d7ac870c4c32fbb4eb.png\"\/><\/p>\n<div><figcaption>\u0432\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u0434\u043b\u044f .env \u0444\u0430\u0439\u043b\u0430<\/figcaption><\/div>\n<\/figure>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0435\u043c venv <\/h2>\n<p>\u0414\u0430, \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0446\u0430\u043d\u044b \u044e\u0437\u0430\u044e\u0442 <a href=\"https:\/\/python-poetry.org\/\" rel=\"noopener noreferrer nofollow\">Poetry<\/a>, \u043d\u043e \u044d\u0442\u043e\u0442 \u0442\u0435\u043a\u0441\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u043b\u0430\u043c\u0435\u0440\u043e\u0432, \u0435\u0441\u043b\u0438 \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u043e \u0443\u043c\u0443 \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0442\u043e \u0432\u043f\u0435\u0440\u0435\u0434, \u0442\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 venv. <\/p>\n<pre><code>python3 -m venv venv <\/code><\/pre>\n<p>\u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e <\/p>\n<pre><code>source venv\/bin\/activate<\/code><\/pre>\n<p>\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c <\/p>\n<pre><code>pip install --upgrade pip<\/code><\/pre>\n<p>\u0441\u0442\u0430\u0432\u0438\u043c uvicorn<\/p>\n<pre><code>pip install uvicorn<\/code><\/pre>\n<p>\u0441\u0442\u0430\u0432\u0438\u043c Fast-api<\/p>\n<pre><code>pip install fastapi<\/code><\/pre>\n<p>\u0441\u0442\u0430\u0432\u0438\u043c aiogram<\/p>\n<pre><code>pip install aiogram<\/code><\/pre>\n<p>\u0441\u0442\u0430\u0432\u0438\u043c python-dotenv, \u044d\u0442\u043e  \u043e\u0434\u0438\u043d \u0438\u0437 \u0442\u0435\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 pip \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0435 \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f <\/p>\n<pre><code>pip install python-dotenv<\/code><\/pre>\n<p>\u0432 <a href=\"http:\/\/README.md\" rel=\"noopener noreferrer nofollow\">README.md<\/a> \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0441\u0442\u0430\u0440\u0442\u0430 <\/p>\n<pre><code>$ uvicorn main:app --reload<\/code><\/pre>\n<p>\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c main.py <\/p>\n<p>\u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u044b \u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 .env<\/p>\n<pre><code>from dotenv import load_dotenv from fastapi import FastAPI  load_dotenv() # \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043c .env \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043a\u0443  TOKEN = os.environ[\"TELEGRAM_TOKEN\"] # \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0437\u0430\u043d\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 BACK_URL = os.environ[\"BACK_URL\"] REACT_URL = os.environ[\"REACT_URL\"]  WEBHOOK_PATH = f\"\/bot\/{TOKEN}\" # \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f WEBHOOK_URL = BACK_URL + WEBHOOK_PATH<\/code><\/pre>\n<p>\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u0447\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <\/p>\n<pre><code>app = FastAPI()  @app.get(\"\/\") async def root():     return {\"message\": \"Hello habr\"}  <\/code><\/pre>\n<p>\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 uvicorn  \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c app = FastAPI \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u0438\u0437 <a href=\"http:\/\/README.md\" rel=\"noopener noreferrer nofollow\">README.md<\/a><\/p>\n<pre><code> uvicorn main:app --reload<\/code><\/pre>\n<p>\u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043d\u0430 BACK_URL \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 , \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0447\u0442\u043e \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u043c\u044b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e  \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438 .env \u0444\u0430\u0438\u043b\u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u0435\u0440\u043d\u043e\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 FastAPI<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/82a\/dda\/844\/82adda844a73bb5511fd3e2b507cf36a.png\" alt=\"\u0443 \u043c\u0435\u043d\u044f \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e\u0432\u0435\u0437\u043b\u043e ))\" title=\"\u0443 \u043c\u0435\u043d\u044f \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e\u0432\u0435\u0437\u043b\u043e ))\" width=\"1004\" height=\"432\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/82a\/dda\/844\/82adda844a73bb5511fd3e2b507cf36a.png\"\/><\/p>\n<div><figcaption>\u0443 \u043c\u0435\u043d\u044f \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e\u0432\u0435\u0437\u043b\u043e ))<\/figcaption><\/div>\n<\/figure>\n<p>\u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c aiogram \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0418 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435 <\/p>\n<pre><code>@app.on_event(\"startup\") #\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0437\u0430\u0441\u044b\u043b\u0430\u0435\u0442 \u0432\u0435\u0431\u0445\u0443\u043a \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c async def on_startup():     webhook_info = await bot.get_webhook_info()     if webhook_info.url != WEBHOOK_URL:         await bot.set_webhook(             url=WEBHOOK_URL         )   @app.post(WEBHOOK_PATH) #\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0442\u0435\u043b\u0433\u0430\u0440\u043c\u0430  async def bot_webhook(update: dict):     telegram_update = types.Update(**update)     Dispatcher.set_current(dp)     Bot.set_current(bot)     await dp.process_update(telegram_update)  <\/code><\/pre>\n<p>\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0441\u0442\u0430\u0440\u044c \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c\u0435<\/p>\n<pre><code>@dp.message_handler(commands=\"start\") async def new_message(message: types.Message):     text = 'REACT'     keyboard = types.InlineKeyboardMarkup()     keyboard.add(types.InlineKeyboardButton('Launch react', web_app=WebAppInfo(url=REACT_URL)))     await bot.send_message(message.chat.id, text, reply_markup=keyboard)   @app.on_event(\"shutdown\") #\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u0441\u0435\u0441\u0438\u0438  async def on_shutdown():     await bot.get_session()     await bot.session.close()     logging.info(\"Bot stopped\") <\/code><\/pre>\n<p>\u0434\u043e\u0431\u0430\u0432\u043b\u044e favicon.iso \u0438 \u0432\u043e\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 <\/p>\n<pre><code>import logging import os  from aiogram import types, Dispatcher, Bot from aiogram.types import WebAppInfo from dotenv import load_dotenv from fastapi import FastAPI from fastapi.responses import FileResponse  load_dotenv()  TOKEN = os.environ[\"TELEGRAM_TOKEN\"] BACK_URL = os.environ[\"BACK_URL\"] REACT_URL = os.environ[\"REACT_URL\"]  WEBHOOK_PATH = f\"\/bot\/{TOKEN}\" WEBHOOK_URL = BACK_URL + WEBHOOK_PATH  bot = Bot(token=TOKEN) dp = Dispatcher(bot)  app = FastAPI()  favicon_path = 'favicon.ico'   @app.get('\/favicon.ico', include_in_schema=False) async def favicon():     return FileResponse(favicon_path)   @app.get(\"\/\") async def root():     return {\"message\": \"Hello habr\"}   @app.on_event(\"startup\") async def on_startup():     webhook_info = await bot.get_webhook_info()     if webhook_info.url != WEBHOOK_URL:         await bot.set_webhook(             url=WEBHOOK_URL         )   @app.post(WEBHOOK_PATH) async def bot_webhook(update: dict):     telegram_update = types.Update(**update)     Dispatcher.set_current(dp)     Bot.set_current(bot)     await dp.process_update(telegram_update)   @app.on_event(\"shutdown\") async def on_shutdown():     await bot.get_session()     await bot.session.close()     logging.info(\"Bot stopped\")   @dp.message_handler(commands=\"start\") async def new_message(message: types.Message):     text = 'REACT'     keyboard = types.InlineKeyboardMarkup()     keyboard.add(types.InlineKeyboardButton('Launch react', web_app=WebAppInfo(url=REACT_URL)))     await bot.send_message(message.chat.id, text, reply_markup=keyboard)   @app.post(WEBHOOK_PATH) async def bot_webhook(update: dict):     telegram_update = types.Update(**update)     Dispatcher.set_current(dp)     Bot.set_current(bot)     await dp.process_update(telegram_update) <\/code><\/pre>\n<p> \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cc2\/be6\/393\/cc2be639326ee3617c0cb59783a08b27.gif\" alt=\"\u0443 \u043c\u0435\u043d\u044f \u0432\u043e\u0440\u043a\u0430\u0435\u0442 \u043e\u0431\u0449\u0435\u043c)\" title=\"\u0443 \u043c\u0435\u043d\u044f \u0432\u043e\u0440\u043a\u0430\u0435\u0442 \u043e\u0431\u0449\u0435\u043c)\" width=\"636\" height=\"586\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cc2\/be6\/393\/cc2be639326ee3617c0cb59783a08b27.gif\"\/><\/p>\n<div><figcaption>\u0443 \u043c\u0435\u043d\u044f \u0432\u043e\u0440\u043a\u0430\u0435\u0442 \u043e\u0431\u0449\u0435\u043c)<\/figcaption><\/div>\n<\/figure>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043e\u043f\u0438\u0441\u0430\u043b \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 #Telegram \u0438 #<a href=\"https:\/\/core.telegram.org\/bots\/webapps\" rel=\"noopener noreferrer nofollow\">Web_Apps for Bots<\/a>. \u041f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438, \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 FAST-API \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e #poetry, \u043d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435 \u0434\u043b\u044f \u043d\u043e\u0432\u0438\u0447\u043a\u043e\u0432. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u0441\u043d\u0443\u043b\u0438\u0441\u044c \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 #ssh \u043a\u043b\u044e\u0447\u0435\u0439, #react, #python, #fast-api, #docker, #docker-compose, #ngrok, #localhost.run, #venv, #uvicorn \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 #shell-script.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/743676\/\"> https:\/\/habr.com\/ru\/articles\/743676\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0434\u043b\u044f \u043b\u0430\u043c\u0435\u0440\u043e\u0432<\/h3>\n<p>\u042f \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e \u0443\u0447\u0438\u043b\u0441\u044f \u043a\u043e\u0434\u0438\u0442\u044c, \u0438 \u0432\u0434\u0440\u0443\u0433 \u0437\u0430\u043c\u0435\u0442\u0438\u043b \u0447\u0442\u043e \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u043b \u0432\u0435\u0431 \u0430\u043f\u0438 \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0444\u0440\u043e\u043d\u0442&#8230;<\/p>\n<p>\u041d\u0430 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u044f \u0443\u0436\u0435 \u0432\u043b\u0430\u0434\u0435\u043b React, Flask \u0438 Django, \u0438 \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u043f\u043b\u0430\u043d\u043a\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e FastAPI.<\/p>\n<p>\u0412\u0435\u0440\u044f \u0432 \u0441\u0432\u043e\u0438 \u0441\u0438\u043b\u044b, \u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b FastAPI \u0438 aiogram. \u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u043c\u043d\u0435 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u043e \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b Telegram API, \u043d\u043e aiogram \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0443\u0434\u043e\u0431\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0441\u043a\u043e\u0440\u044f\u044e\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443.<\/p>\n<h3>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/h3>\n<p>Django \u0438 Flask \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u044b (\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b Jinja2), \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043a\u043e\u0434, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 (HTML, JS, CSS, TS \u0438 \u0442. \u0434.), \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0443 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043b\u044f \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434\u0430.<\/p>\n<p>\u043e\u0434\u043d\u0430\u043a\u043e Fast-api \u0438 React, \u043d\u0443\u0436\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u0445 &#8230;<\/p>\n<p>\u042f \u043f\u043e\u043d\u0438\u043c\u0430\u044e, \u0447\u0442\u043e \u043d\u0430\u0439\u0434\u0443\u0442\u0441\u044f \u043b\u044e\u0434\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043a\u0430\u0436\u0443\u0442: &#171;\u0417\u0430\u0447\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043b\u044f React, \u0435\u0441\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Knockout.js \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435?&#187; &#8212; \u0414\u0430, \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043d\u043e \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438, \u0430 \u043d\u0435 \u043a\u043e\u0441\u0442\u044b\u043b\u0438 \u043d\u0430 \u043a\u043e\u0441\u0442\u044b\u043b\u044f\u0445, \u0447\u0442\u043e\u0431\u044b \u043a \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0443 \u0432\u0430\u0441 \u0431\u044b\u043b \u0446\u0435\u043d\u043d\u044b\u0439 \u043e\u043f\u044b\u0442 \u0432 \u0440\u0435\u0437\u044e\u043c\u0435, \u0430 \u043d\u0435 \u043f\u043e\u0432\u043e\u0434 \u0434\u043b\u044f \u043f\u0435\u043d\u0441\u0438\u0438))<\/p>\n<p>\u042f \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0441\u044f \u0441 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0435\u0433\u043e Knockout,js \u0438 Python 2, \u0432\u0441\u0435 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0435. \u0421\u0445\u0435\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043a \u0442\u043e\u043c\u0443 \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u0434\u0436\u0443\u043d\u043e\u0432 \u0438 \u043f\u043b\u0430\u0442\u0438\u0442\u044c \u0438\u043c \u043c\u0435\u043d\u044c\u0448\u0435, \u0432\u0435\u0434\u044c \u0432\u0441\u0435\u0445 \u043e\u0431\u0443\u0447\u0430\u044e\u0442 Django \u043d\u0430 \u043a\u0443\u0440\u0441\u0430\u0445).<\/p>\n<h3>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 <\/h3>\n<p>\u0412\u043e\u0442 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 &#8212; FastAPI \u0438 React. \u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0445 \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0441 Telegram API. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0430\u043a\u043e\u0439 \u0441\u0432\u044f\u0437\u0438: \u0440\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, FastAPI \u0438 Telegram \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0447\u0435\u0440\u0435\u0437 webhook. \u0427\u0442\u043e\u0431\u044b \u0438\u0445 \u0441\u0432\u0435\u0441\u0442\u0438 \u0432\u043c\u0435\u0441\u0442\u0435, \u043c\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441 Telegram \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043e\u0442 ngrok, \u0438 \u0442\u043e\u043a\u0435\u043d \u0431\u043e\u0442\u0430 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 .env. \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0430\u0434\u0440\u0435\u0441 ngrok \u0432 .env, \u0438 FastAPI \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0441\u0432\u044f\u0437\u044c \u0441 Telegram \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e ngrok, \u0434\u0430\u0436\u0435 \u0432 \u043f\u043b\u0430\u0442\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0430\u0434\u0440\u0435\u0441, \u0430 \u0443 \u043c\u0435\u043d\u044f \u0444\u0440\u043e\u043d\u0442\u044d\u043d\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u0442\u0443. \u041e\u0434\u043d\u0430\u043a\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 localhost.run. \u041e\u043d\u0430 \u0438\u043c\u0435\u0435\u0442 \u0441\u0445\u043e\u0436\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0441 ngrok, \u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0447\u0443\u0442\u043a\u0430 \u0441\u043b\u043e\u0436\u043d\u0435\u0435.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u043b\u0430\u043d \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f \u0431\u044b \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u043b\u0441\u044f <\/p>\n<ol>\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c localhost.run \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 3000 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0431\u044d\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c React \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 3000<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c ngrok \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 8000 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c Fast-api \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 8000<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043b\u0430\u043d \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439, \u043a\u0430\u043a \u0448\u0432\u0435\u0439\u0446\u0430\u0440\u0441\u043a\u0438\u0435 \u0447\u0430\u0441\u044b. <\/p>\n<h3>1. localhost.run <\/h3>\n<p>\u0417\u0430\u0445\u043e\u0434\u0438\u043c \u043d\u0430 <a href=\"https:\/\/admin.localhost.run\/\" rel=\"noopener noreferrer nofollow\">https:\/\/admin.localhost.run\/<\/a> \u0440\u0435\u0433\u0430\u0435\u043c\u0441\u044f\\\u043b\u043e\u0433\u0438\u043d\u0438\u043c\u0441\u044f. <\/p>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c shh \u043a\u043b\u044e\u0447  <a href=\"https:\/\/docs.gitlab.com\/ee\/user\/ssh.html#rsa-ssh-keys\" rel=\"noopener noreferrer nofollow\">\u043e\u0440\u0438\u0433.  \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0441\u0441\u043a\u043e\u043c<\/a>. \u041a\u043b\u044e\u0447 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 2\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0439 \u0438 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0439. \u0437\u0430\u0445\u043e\u0434\u0438\u043c \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u0438 \u043f\u0438\u0448\u0435\u043c <\/p>\n<pre><code>ssh-keygen -t rsa -b 2048 -C \"&lt;comment>\"<\/code><\/pre>\n<p>*\u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0435\u043c\u0435\u0439\u043b<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u044d\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u0430\u043a \u043e\u0442\u0432\u0435\u0442<\/figcaption><\/div>\n<\/figure>\n<p>\u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043b\u044e\u0447\u0430. \u0438 \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u043f\u0443\u0442\u044c. \u0435\u0441\u043b\u0438 \u043d\u0435 \u0432\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u043c\u044f \u0442\u043e \u043a\u043b\u044e\u0447\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0441 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u043c\u0438 \u0438\u043c\u0435\u043d\u0430\u043c\u0438 id_rsa \u0438 id_rsa.pub<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0436\u043c\u0435\u043c \u0435\u043d\u0442\u0435\u0440 , \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0447\u0442\u043e \u043a\u043b\u044e\u0447 \u0433\u043e\u0442\u043e\u0432. <\/figcaption><\/div>\n<\/figure>\n<p>\u0438\u0434\u0435\u043c \u0432  \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u043a\u043b\u044e\u0447\u0430, \u0436\u043c\u0435\u043c ls -1 \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0447\u0442\u043e \u043f\u0440\u0438\u0448\u043b\u0438 \u0432 \u043d\u0443\u0436\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u0438 \u043a\u043b\u044e\u0447\u0438 \u0433\u043e\u0442\u043e\u0432\u044b \u0438 \u0436\u0434\u0443\u0442 \u043d\u0430\u0441. <\/p>\n<pre><code>ls -1<\/code><\/pre>\n<figure class=\"full-width\">\n<div><figcaption>\u043a\u0430\u043a \u044f \u043f\u043e\u043d\u044f\u043b  \u0432 \u043f\u0430\u043f\u043a\u0443 .ssh \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u043f\u043e\u043f\u0430\u0441\u0442\u044c  <\/figcaption><\/div>\n<\/figure>\n<p>id_rsa \u0438 id_rsa.pub \u044d\u0442\u043e \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u0438 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u043a\u043b\u044e\u0447\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0432\u0435\u043d\u043d\u043e. \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c id_rsa.pub  \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e vim \u0438\u043b\u0438 nano. \u0415\u0441\u043b\u0438 \u043d\u0435\u0442 vim \u0442\u043e \u0441\u0442\u0430vim vim))<\/p>\n<pre><code>vim id_rsa.pub<\/code><\/pre>\n<figure class=\"full-width\"><\/figure>\n<p>\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438(\u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 shh \u0438 \u0434\u043e \u043a\u043e\u043d\u0446\u0430 \u0442\u0435\u043a\u0441\u0442\u0430)<br \/>\u0434\u0430\u043b\u044c\u0448\u0435 \u0432\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u0432\u0438\u043c\u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0436\u043c\u0435\u043c \u201c:\u201d \u0438 \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u043c q! \u0438 \u0436\u043c\u0435\u043c \u0435\u043d\u0442\u044b\u0440. <\/p>\n<p>\u0438\u0434\u0435\u043c \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u043d\u0430 <a href=\"https:\/\/admin.localhost.run\/#\/keys\" rel=\"noopener noreferrer nofollow\">https:\/\/admin.localhost.run\/#\/keys<\/a> \u0432\u0432\u043e\u0434\u0438\u043c \u0442\u0430\u043c \u044d\u0442\u043e\u0442 \u043a\u043b\u044e\u0447<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0436\u043c\u0435\u043c \u0441\u0430\u0431\u043c\u0438\u0442<\/figcaption><\/div>\n<\/figure>\n<p>\u0434\u0430\u043b\u044c\u0448\u0435 \u0438\u0434\u0435\u043c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c<\/p>\n<pre><code>ssh -R 80:localhost:3000 localhost.run<\/code><\/pre>\n<p>\u0427\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0435\u0442 \u044d\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 <a href=\"https:\/\/localhost.run\/docs\/\" rel=\"noopener noreferrer nofollow\">\u043c\u043e\u0436\u043d\u043e\u043f\u043e\u0447\u0442\u0438\u0442\u0430\u0442\u044c \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/a><\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0430\u0448 \u0431\u0435\u043b\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 3000<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0435 \u043f\u043e\u0440\u0442 3003 \u0430 \u043d\u0435 3000<\/figcaption><\/div>\n<\/figure>\n<p>\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u0432 .env \u0431\u044d\u043a\u0430 <\/p>\n<p>\u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0441\u0442\u0430\u043b\u043e \u0432\u0440\u0435\u043c\u044f REACT<\/p>\n<h3>2. REACT<\/h3>\n<p>\u0418\u0442\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0431\u0435\u0437 \u0442\u0430\u043d\u0446\u0435\u0432,<a href=\"https:\/\/github.com\/dandaniel5\/newReactCompose\/tree\/main\" rel=\"noopener noreferrer nofollow\"> \u044f \u0441\u0434\u0435\u043b\u044f\u043b\u044c \u0432\u0438\u0437\u0437\u0430\u0440\u0434 \u0441\u043a\u0440\u0438\u043f\u0442<\/a>. \u041e\u0442\u043c\u0435\u0447\u0443 \u0447\u0442\u043e \u043e\u043d \u0434\u0430\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u0442\u044c js\/jsx, yarn\/npm, \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0434\u043e\u043a\u0435\u0440 \u0438 \u0434\u043e\u043a\u0435\u0440 \u043a\u043e\u043c\u043f\u043e\u0443\u0437 \u0441 \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044b\u043c\u0438 \u043f\u043e\u0440\u0442\u0430\u043c\u0438, \u0430 \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u0432\u044b\u043d\u0435\u0441\u0435\u043d \u0432 \u0432\u0430\u043b\u0438\u0443\u043c \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u0441\u0431\u043e\u0440\u043a\u0438. <\/p>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043e\u0437\u0434\u0430\u0435\u043c create_react_compose_app.sh \u0438\u043b\u0438 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0441 <a href=\"https:\/\/github.com\/dandaniel5\/newReactCompose\/blob\/main\/create_react_copmpose_app.sh\" rel=\"noopener noreferrer nofollow\">github<\/a>.<\/p>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u043c , \u043d\u0430 \u043c\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>chmod +x create_react_compose_app.sh<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0441\u043a\u0440\u0438\u043f\u0442:<\/p>\n<pre><code>bash create_react_copmpose_app.sh<\/code><\/pre>\n<figure class=\"full-width\">\n<div><figcaption>\u0434\u0430\u043b\u044c\u0448\u0435 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u0432\u0441\u0435 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0442\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0449\u0435\u043b\u043a\u0430\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b. \u0438\u043c\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u044d\u0442\u043e pwd + web re , npm , js<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\">\n<div><figcaption>\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0434\u043e\u043a\u0435\u0440\u0444\u0430\u0438\u043b <\/figcaption><\/div>\n<\/figure>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0434\u043e\u043a\u0435\u0440, \u043f\u043e\u0441\u043b\u0435 \u0432\u0432\u043e\u0434\u0438\u043c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c <\/p>\n<pre><code>docker-compose up<\/code><\/pre>\n<p>\u0418 \u0432\u043e\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u043e \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 3000, \u0442\u0435\u043f\u0435\u0440\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0438\u0434\u0435\u043c \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432 localhost.run<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0438 \u0432\u043e\u0442 \u043c\u044b \u043e\u043d\u043b\u0430\u0439\u043d<\/figcaption><\/div>\n<\/figure>\n<p>\u0418\u0434\u0435\u043c \u0432 <\/p>\n<figure class=\"\">\n<div><figcaption>\u0438\u0434\u0435\u043c \u0432 <\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c index.html \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0443\u0434\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c <\/p>\n<pre><code>&lt;script src=\"https:\/\/telegram.org\/js\/telegram-web-app.js\">&lt;\/script><\/code><\/pre>\n<figure class=\"full-width\">\n<div><figcaption>\u043f\u0440\u044f\u043c\u043e \u0432 head<\/figcaption><\/div>\n<\/figure>\n<p>\u0418 \u0437\u0430\u043c\u0435\u043d\u0438\u043c  <\/p>\n<pre><code>&lt;p>  Edit &lt;code>src\/App.js&lt;\/code> and save to reload.&lt;\/p>   &lt;a           className=\"App-link\"           href=\"https:\/\/reactjs.org\"           target=\"_blank\"           rel=\"noopener noreferrer\"         >           Learn React         &lt;\/a><\/code><\/pre>\n<p>\u041d\u0430 <\/p>\n<pre><code>&lt;p> Hellow Habr. &lt;\/p><\/code><\/pre>\n<p>\u0412 src\/App.js<\/p>\n<p>\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u043b localhost.run<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e\u0432\u0435\u0437\u043b\u043e \ud83d\ude42<\/figcaption><\/div>\n<\/figure>\n<h3>3. Ngrok<\/h3>\n<p>\u0438\u0434\u0435\u043c \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u043d\u0430 <a href=\"https:\/\/ngrok.com\/\" rel=\"noopener noreferrer nofollow\">https:\/\/ngrok.com\/<\/a>  \u0420\u0435\u0433\u0430\u0435\u043c\u0441\u044f\/\u043b\u043e\u0433\u0438\u043d\u0438\u043c\u0441\u044f<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u044e \u043f\u043e\u0434 \u0441\u0432\u043e\u044e \u043e\u0441 <\/figcaption><\/div>\n<\/figure>\n<p>\u0438\u0434\u0435\u043c \u0432 <a href=\"https:\/\/dashboard.ngrok.com\/get-started\/setup\" rel=\"noopener noreferrer nofollow\">https:\/\/dashboard.ngrok.com\/get-started\/setup<\/a> <\/p>\n<p>\u0434\u0435\u043b\u0430\u043c \u0432\u0441\u0435 \u043f\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p> \u0440\u0430\u0437\u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c zip<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u043b\u044e\u0447 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433, \u0443\u0434\u043e\u0431\u043d\u043e \u0447\u0442\u043e \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0441\u0440\u0430\u0437\u0443 \u0434\u0430\u044e\u0442\u0441\u044f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0441 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u043a\u043b\u044e\u0447\u043e\u043c  <\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u043d\u0435 \u043d\u0430\u0434\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u044d\u0442\u043e \u0433\u043e\u0442\u043e\u0432\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430. \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u0442\u0443\u0442 <a href=\"https:\/\/ngrok.com\/docs\" rel=\"noopener noreferrer nofollow\">\u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e ngrok<\/a><\/figcaption><\/div>\n<\/figure>\n<\/li>\n<li>\n<p>\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c ngrok \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 8000<\/p>\n<pre><code>ngrok http 8000<\/code><\/pre>\n<\/li>\n<\/ul>\n<figure class=\"full-width\">\n<div><figcaption>\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0442\u043e\u0440\u043e\u0439 \u0431\u0435\u043b\u044b\u0439 \u0430\u043f\u0438 \u0430\u0434\u0440\u0435\u0441\u0441<\/figcaption><\/div>\n<\/figure>\n<h3>4. Fast-API<\/h3>\n<p>\u0437\u0430\u0445\u043e\u0434\u0438\u043c \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0437\u0430\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0441\u0442\u0440\u0435\u043b\u043a\u0435 <\/figcaption><\/div>\n<\/figure>\n<p>\u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0430\u043f\u043a\u0443 Fast-API \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0443<\/p>\n<pre><code>mkdir Fast-API<\/code><\/pre>\n<p>\u043f\u0435\u0440\u0435\u0434\u0435\u043c \u0432 \u043d\u0435\u0435 <\/p>\n<pre><code>cd Fast-API<\/code><\/pre>\n<p>\u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c <a href=\"http:\/\/main.py\" rel=\"noopener noreferrer nofollow\">main.py<\/a> \u0438 <a href=\"http:\/\/README.md\" rel=\"noopener noreferrer nofollow\">README.md<\/a>, .env c \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0436\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b  touch. \u041b\u0435\u0433\u043a\u043e \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043f\u0440\u043e \u043d\u0435 \u0435\u0441\u0442\u044c \u043f\u0435\u0441\u043d\u044f \u0443 <a href=\"https:\/\/www.youtube.com\/watch?v=0Gkhol2Q1og\" rel=\"noopener noreferrer nofollow\"><strong>Daft Punk &#8212; Touch<\/strong><\/a><strong> <\/strong><\/p>\n<p> \u0441\u043e\u0437\u0434\u0430\u0435\u043c  \u0444\u0430\u0438\u043b \u0438 \u043a\u043b\u0430\u0434\u0435\u043c \u0442\u0443\u0434\u0430 \u0430\u0434\u0440\u0435\u0441 \u0438\u0437 localhost.run , ngrok , \u0442\u043e\u043a\u0435\u043d\u0431\u043e\u0442\u0430 &#8230;<\/p>\n<pre><code>touch .env<\/code><\/pre>\n<figure class=\"full-width\">\n<div><figcaption>\u0432\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u0434\u043b\u044f .env \u0444\u0430\u0439\u043b\u0430<\/figcaption><\/div>\n<\/figure>\n<h2>\u0421\u043e\u0437\u0434\u0430\u0435\u043c venv <\/h2>\n<p>\u0414\u0430, \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0446\u0430\u043d\u044b \u044e\u0437\u0430\u044e\u0442 <a href=\"https:\/\/python-poetry.org\/\" rel=\"noopener noreferrer nofollow\">Poetry<\/a>, \u043d\u043e \u044d\u0442\u043e\u0442 \u0442\u0435\u043a\u0441\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u043b\u0430\u043c\u0435\u0440\u043e\u0432, \u0435\u0441\u043b\u0438 \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u043e \u0443\u043c\u0443 \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0442\u043e \u0432\u043f\u0435\u0440\u0435\u0434, \u0442\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 venv. <\/p>\n<pre><code>python3 -m venv venv <\/code><\/pre>\n<p>\u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e <\/p>\n<pre><code>source venv\/bin\/activate<\/code><\/pre>\n<p>\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c <\/p>\n<pre><code>pip install --upgrade pip<\/code><\/pre>\n<p>\u0441\u0442\u0430\u0432\u0438\u043c uvicorn<\/p>\n<pre><code>pip install uvicorn<\/code><\/pre>\n<p>\u0441\u0442\u0430\u0432\u0438\u043c Fast-api<\/p>\n<pre><code>pip install fastapi<\/code><\/pre>\n<p>\u0441\u0442\u0430\u0432\u0438\u043c aiogram<\/p>\n<pre><code>pip install aiogram<\/code><\/pre>\n<p>\u0441\u0442\u0430\u0432\u0438\u043c python-dotenv, \u044d\u0442\u043e  \u043e\u0434\u0438\u043d \u0438\u0437 \u0442\u0435\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 pip \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0435 \u0442\u0430\u043a \u043a\u0430\u043a \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f <\/p>\n<pre><code>pip install python-dotenv<\/code><\/pre>\n<p>\u0432 <a href=\"http:\/\/README.md\" rel=\"noopener noreferrer nofollow\">README.md<\/a> \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0441\u0442\u0430\u0440\u0442\u0430 <\/p>\n<pre><code>$ uvicorn main:app --reload<\/code><\/pre>\n<p>\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c main.py <\/p>\n<p>\u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u044b \u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 .env<\/p>\n<pre><code>from dotenv import load_dotenv from fastapi import FastAPI  load_dotenv() # \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043c .env \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043a\u0443  TOKEN = os.environ[\"TELEGRAM_TOKEN\"] # \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0437\u0430\u043d\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 BACK_URL = os.environ[\"BACK_URL\"] REACT_URL = os.environ[\"REACT_URL\"]  WEBHOOK_PATH = f\"\/bot\/{TOKEN}\" # \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f WEBHOOK_URL = BACK_URL + WEBHOOK_PATH<\/code><\/pre>\n<p>\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u0447\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <\/p>\n<pre><code>app = FastAPI()  @app.get(\"\/\") async def root():     return {\"message\": \"Hello habr\"}  <\/code><\/pre>\n<p>\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 uvicorn  \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c app = FastAPI \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u0438\u0437 <a href=\"http:\/\/README.md\" rel=\"noopener noreferrer nofollow\">README.md<\/a><\/p>\n<pre><code> uvicorn main:app --reload<\/code><\/pre>\n<p>\u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043d\u0430 BACK_URL \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 , \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0447\u0442\u043e \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u043c\u044b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e  \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438 .env \u0444\u0430\u0438\u043b\u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u0435\u0440\u043d\u043e\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 FastAPI<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0443 \u043c\u0435\u043d\u044f \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e\u0432\u0435\u0437\u043b\u043e ))<\/figcaption><\/div>\n<\/figure>\n<p>\u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c aiogram \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0418 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435 <\/p>\n<pre><code>@app.on_event(\"startup\") #\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0437\u0430\u0441\u044b\u043b\u0430\u0435\u0442 \u0432\u0435\u0431\u0445\u0443\u043a \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c async def on_startup():     webhook_info = await bot.get_webhook_info()     if webhook_info.url != WEBHOOK_URL:         await bot.set_webhook(             url=WEBHOOK_URL         )   @app.post(WEBHOOK_PATH) #\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0442\u0435\u043b\u0433\u0430\u0440\u043c\u0430  async def bot_webhook(update: dict):     telegram_update = types.Update(**update)     Dispatcher.set_current(dp)     Bot.set_current(bot)     await dp.process_update(telegram_update)  <\/code><\/pre>\n<p>\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0441\u0442\u0430\u0440\u044c \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c\u0435<\/p>\n<pre><code>@dp.message_handler(commands=\"start\") async def new_message(message: types.Message):     text = 'REACT'     keyboard = types.InlineKeyboardMarkup()     keyboard.add(types.InlineKeyboardButton('Launch react', web_app=WebAppInfo(url=REACT_URL)))     await bot.send_message(message.chat.id, text, reply_markup=keyboard)   @app.on_event(\"shutdown\") #\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u0441\u0435\u0441\u0438\u0438  async def on_shutdown():     await bot.get_session()     await bot.session.close()     logging.info(\"Bot stopped\") <\/code><\/pre>\n<p>\u0434\u043e\u0431\u0430\u0432\u043b\u044e favicon.iso \u0438 \u0432\u043e\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 <\/p>\n<pre><code>import logging import os  from aiogram import types, Dispatcher, Bot from aiogram.types import WebAppInfo from dotenv import load_dotenv from fastapi import FastAPI from fastapi.responses import FileResponse  load_dotenv()  TOKEN = os.environ[\"TELEGRAM_TOKEN\"] BACK_URL = os.environ[\"BACK_URL\"] REACT_URL = os.environ[\"REACT_URL\"]  WEBHOOK_PATH = f\"\/bot\/{TOKEN}\" WEBHOOK_URL = BACK_URL + WEBHOOK_PATH  bot = Bot(token=TOKEN) dp = Dispatcher(bot)  app = FastAPI()  favicon_path = 'favicon.ico'   @app.get('\/favicon.ico', include_in_schema=False) async def favicon():     return FileResponse(favicon_path)   @app.get(\"\/\") async def root():     return {\"message\": \"Hello habr\"}   @app.on_event(\"startup\") async def on_startup():     webhook_info = await bot.get_webhook_info()     if webhook_info.url != WEBHOOK_URL:         await bot.set_webhook(             url=WEBHOOK_URL         )   @app.post(WEBHOOK_PATH) async def bot_webhook(update: dict):     telegram_update = types.Update(**update)     Dispatcher.set_current(dp)     Bot.set_current(bot)     await dp.process_update(telegram_update)   @app.on_event(\"shutdown\") async def on_shutdown():     await bot.get_session()     await bot.session.close()     logging.info(\"Bot stopped\")   @dp.message_handler(commands=\"start\") async def new_message(message: types.Message):     text = 'REACT'     keyboard = types.InlineKeyboardMarkup()     keyboard.add(types.InlineKeyboardButton('Launch react', web_app=WebAppInfo(url=REACT_URL)))     await bot.send_message(message.chat.id, text, reply_markup=keyboard)   @app.post(WEBHOOK_PATH) async def bot_webhook(update: dict):     telegram_update =<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-349305","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/349305","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=349305"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/349305\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=349305"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=349305"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=349305"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}