Тёмный

Next.js setup: Деплой на VPS | Jest | Playwright | CI/CD | Sentry 

Евгений Паромов | Front-end
Подписаться 9 тыс.
Просмотров 25 тыс.
50% 1

Мой курс по FSD paromovevg.ru/courses/fsd 🙂
Исходники:
github.com/micro-course/core/...
Волшебный файлик: wonderful-deer-c82.notion.sit...
Мой telegram канал:
t.me/cleanfrontend
Это первое видео я в серии, где я на ваших глазах разработаю продукт с нуля, до заработка первых денег. Особенностью серии будет, что я не буду "срезать углы". Буду использовать FDS архитектуру, тестирование, CI/CD, и все самые актуальные на данный момент инструменты.
Полный стек проекта:
React, Next.js app router, FSD архитектура, postgresql, prisma, zod, @tanstack/react-query, react-hook-form, tailwindcss, shadcn/ui, next-auth, jest , @testing-library/react, playwright
00:00:00 - 0.1 О серии видео
00:01:36 - 0.2 Особенности проекта и меня
00:03:52 - 0.3 Стек проекта
00:08:10 - 0.4 Что будем делать в этом видео
00:11:02 - 1.1 Инициализация проекта
00:23:30 - 1.2 SSH важный ликбез
00:36:02 - 1.3 Загружаем код в репозиторий
00:39:22 - 1.4 Настройка VPS
00:44:56 - 1.5 Настройка пользователя и ssh ключей
00:51:49 - 1.6 Запускаем Next.js на сервере
00:58:37 - 1.7 Запускаем Next.js через pm2 в фоне
01:01:41 - 1.8 Настраиваем фаервол
01:03:38 - 1.9 Настраиваем nginx
01:10:47 - 1.10 Настраиваем https
01:15:21 - 2.1 Добавляем prisma в проект
01:25:25 - 2.2 Делаем пример работы с базой на fsd
02:04:16 - 2.3 Как будем работать с .env
02:07:17 - 2.4 Настраиваем staging для работы с базой
02:13:42 - 3.1 Добавляем jest в проект
02:21:59 - 3.2 Добавляем playwright в проект
02:31:40 - 4.1 CI: Добавляем запуск jest eslint на PR
02:42:23 - 4.2 CD: Настраиваем deploy на пуш в main
03:07:11 - 4.3 CI: Запускаем plawright после деплоя в staging
03:13:53 - 5 Настраиваем production
03:34:48 - 6 Настройка sentry
03:55:29 - 7 Путь фичи

Наука

Опубликовано:

 

1 июн 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 96   
@paromovevg
@paromovevg 4 месяца назад
Если вам понравился хостинг, переходите по этой ссылке, мне бонусики будут капать, и вам тоже) timeweb.cloud/r/paromovevg
@MegaMaxxon
@MegaMaxxon 5 месяцев назад
Вау, если прям со всей инфраструктурой, настройкой ci/cd, базой, тестами, nginx и вот это все то это мега круто 👍
@vladimirbavtenko9080
@vladimirbavtenko9080 5 месяцев назад
Я в начале видео, но уже хочу все это как минимум повторить на своем проекте и надеюсь, что все будет подробно. Это уникальный контент по реальной разработке и вообще Евгению огромная благодарность за естественную и не занудную подачу материала, тут конечно и голос, и меняющаяся интонация, и свой личный подход с высоты опыта - просто огонь! Я много чего смотрел и смотрю по разработке, но Евгений - уникальный и то, что он делает тоже никто ранее так не делал, да и не сможет из-за особенностей личности в хорошем смысле. Для меня - это топ канал. Желаю и, сам этого очень хочу, чтобы качество контента никогда не падало, с нетерпением жду уже продолжения.
@kh4ff
@kh4ff 6 дней назад
Жаль, что раньше не нашёл твой канал. Таких туториалов практически нет на ютубе. Теперь мне хотябы ясно, куда копать, какие технологии изучать, чтобы правильно деплоить на vps.
@grol5555
@grol5555 2 месяца назад
Очень понравилась схема, деплоя, простая и понятная, как раз для pet-проектов. А то начинаешь смотреть видео как всё контеризируют, затем docker-compose и уже остаётся один шаг до kubernetes. Убиваешь уйму времени именно в DevOps для достаточно простого pet-проекта. А в этом видео всё просто, хорошее видео.
@dmitrysvetlov6001
@dmitrysvetlov6001 4 месяца назад
Канал находка, такого контента даже в en сегменте не видел. потрясающая подача, отличный разбор смежных тем. Каналу удачи.
@abvgd12357
@abvgd12357 5 месяцев назад
Замечательный контент! Приятно узнавать не затертую до дыр инфу, а что то полезное из так называемой "реальной разработки". Лайк и подписка однозначно!
@user-mi1hq1dz2b
@user-mi1hq1dz2b Месяц назад
Спасибо, Евгений! Очень качественное видео. На просторах ютуба и гугла такго вообще нет. Так еще и файлик создал, который очень помогает мне. Эта база мне очень пригодилась на работе.
@ell1ar
@ell1ar 5 месяцев назад
29:22, Евгений, мне кажется здесь важная неточность (я могу ошибаться, поправьте): Клиент отправляет серверу просто pub ключ, сервер проверяет в списке, есть ли такой ключ (~/.ssh/authorized_keys) и если да, то он с помощью него шифрует случайную строку, отсылает в зашифрованном виде клиенту. Клиент, с помощью секретного ключа, расшифровывает сообщение и отправляет назад серверу. Сервер проверяет, что если расшифрованное клиентом сообщение совпадает с его первоначальным, то вход успешен. Потому что pub ключик, по сути, просто "замок", которым можно закрыть "ящичек". Ничего этот ключ не расшифровывает. А по вашей логике получается наоборот :)
@krasovsky1
@krasovsky1 5 месяцев назад
Супер контент! И без воды. Огромное спасибо👍
@leshamaybe
@leshamaybe 5 месяцев назад
Твой канал кладезь полезного. За разжевывание деплоя большое спасибо!
@Kinslayer696
@Kinslayer696 5 месяцев назад
Видео огонь! Могу представить сколько потребовалось времени и сил чтобы все это отснять и смонтировать. Спасибо большое👍
@Zer0IsNotJustNumber
@Zer0IsNotJustNumber 5 месяцев назад
не успел посмотреть, уже лайк просто потому что знаю что это того стоит!
@Arman-kp8jf
@Arman-kp8jf 5 месяцев назад
Очень хороший выбор контента. Удачи!!!
@DoSmth
@DoSmth 5 месяцев назад
Привет! Было бы супер увидеть подключение оплаты! Очень мало инфв об этом в ру сегменте, спасибо)
@user-vk4si1oz7w
@user-vk4si1oz7w 5 месяцев назад
Ну до чего приятный паренек! Прям богом дано про чтото рассказыаать, и здорово что выбрал программирование)) лайк, подписка, хоть я и на вью пишу))
@GAccountMe
@GAccountMe 5 месяцев назад
Начал смотреть, похоже на что-то очень годное! Спасибо=)) Когда продолжение?=)
@user-lb9oq9up1u
@user-lb9oq9up1u 5 месяцев назад
Дружище только не бросай прошу! я хочу делать этот проект вместе с тобой
@YakubAx
@YakubAx 5 месяцев назад
Супер видео ждем продолжение 🔥
@user-zh6fh6lj8j
@user-zh6fh6lj8j 13 дней назад
Топовый контент, очень сильно помог!
@WorldworkMay
@WorldworkMay Месяц назад
Шикарный контент! Спасибо!
@user-df2hp7zm8q
@user-df2hp7zm8q 3 месяца назад
Спасибо Евгений. Это наикрутейшее видео. Продолжу дальше смотреть твои видео.
@pavelsmirnov9818
@pavelsmirnov9818 5 месяцев назад
Крутой контент, большое спасибо
@sardorsultanov3409
@sardorsultanov3409 5 месяцев назад
Я только начал изучать ci/cd а ваш видео просто топ по понятности
@martcarrefour
@martcarrefour 5 месяцев назад
Очень крутое видео! Не подскажете, когда ждать продолжения?
@maxblock5233
@maxblock5233 5 месяцев назад
Очень вовремя, круто, спасибо большое
@user-hg3oi4qw2d
@user-hg3oi4qw2d 4 месяца назад
Очень круто! Продолжение ждем...
@ringnull
@ringnull 5 месяцев назад
Серьёзно ты подошел к вопросу. То что надо.
@user-hg3oi4qw2d
@user-hg3oi4qw2d 5 месяцев назад
Круто, это очень круто!!!! Ждем продолжения, очень очень!!!!
@artemvictorovich6731
@artemvictorovich6731 4 месяца назад
Привет! Спасибо за видео! Подскажи, пожалуйста, какой микрофон используешь ?
@archee7309
@archee7309 5 месяцев назад
А когда вторая часть? С нетерпением жду продолжения, твои уроки на вес золота
@paromovevg
@paromovevg 4 месяца назад
Уже на канале)
@narwhal6422
@narwhal6422 3 месяца назад
Ура я сделал это, правда у меня это заняло часов 25🎉
@user-wh9mc2po7g
@user-wh9mc2po7g 5 месяцев назад
Топ контент, будем смотреть/учиться
@GAccountMe
@GAccountMe 5 месяцев назад
Я только разбираюсь с next и fsd, по этому могу заблуждаться. Но мне кажется, что серверные экшены нужно все же хранить отдельно, как отдельный слой абстракции. Ты абстрагировал работу с БД в архитектурный слой репозитория - это прекрасно, я тоже так делаю, но тут же принес этот слой в tsx файл, где у нас ui слой, что, как по мне - плохо, следующий шаг - это писать slq в компонентах=)). Например я стараюсь вынести из компонентов всю бизнеслогинку как раз таки в серверные экшены, а в компонентах оставлять только то, что касается ui и обработки событий, к тому же, в моих кейсах серверные экшены переиспользуются и они довольно объемные по коду, потому что, зачастую содержат много проверок и последовательной логики, что-то по типу - существует ли пользователь, создал ли этот пользователь курс, который хочет удалить - ну и т.д. Если это лежит отдельно это и тестируется лучше. Ну и конечно, я бы все же создал entity для курса и экшен по удалению курса был бы там, а фича бы его дергала, ну ты говоришь что осознанно сделал не так=) Так же вопрос - почему create-course-form лежит в фиче course-list, название явно же говорит что это фича про листинг, мне кажется что нужна фича по типу create-course, ну или все же создать entity для курса и положить эту форму там - вроде это не противоречит fsd, хотя все же эта функциональность явно фича. Еще по типам, ты говорил, что делаешь типы отдельно от тех, что генерит призма - тоже так делаю, но я наследуюсь от типа сущности который дает призма и проста пикаю нужные поля, это все же дает какую-то связь сущностей с базы и типов в приложении, например если в базе поменяется поле name на username, то тайпскрипт скажет что поля name нет в моем типе для приложения. Видос крутой, спасибо! Практически все авторы на ютубе, юдеми и других площадках делают, по принципу - работает и хорошо, очень мало материала по архитектуре, очень не хватает такого контента
@paromovevg
@paromovevg 5 месяцев назад
По факту тут не очень показательный пример, так как приложение маленькое и это посути был тестовый пример. - По поводу наследования от типа базы данных, советую посмотреть в сторону чистой архитектуры. Там база и её структура - есть следствие бизнес логики а не наоборот. Если база поменятся, то поменяется только код, который будет адаптировать структуру базы к бизнес сущности, не придётся менять весь остальной код приложения - По поводу экшонов в компонентах. Компонент и так серверный, исполняется на сервере. Я сказал важный момент. Экшон это контроллер, а значит в нём вообще ничего почти не будет. Весь реальный код будет в других модулях. Но просто этот пример был сшилком простым, что бы это делать (Но в следующем видео, я всё равно полностью эшконы вынес в отдельный файл) - По поводу фич и сущностей. Я говорил, что это немного изменённая моя версия fsd. Она решает вопрос слишком большого coupling. Подробнее тоже будет в следющем видео
@vadikcvirko179
@vadikcvirko179 5 месяцев назад
Давай вторую часть, я поставил лайк и подписался.
@goldovyidozhdik3430
@goldovyidozhdik3430 4 месяца назад
Евгений такой вопрос, а если мне надо будет сделать сайт юр лицу по похожему алгоритму действий, как потом передать его в собственность заказчику? Домен и сервер наверное можно легко переоформить, а с гитхабом непонятно. Может сразу сделать гитхаб и сервер на имя заказчика а самому просто получить доступ? но звучит не надёжно или заказчик просто скачивает файлы с моего репозитория и делает с ними что хочет, а я свой удаляю?
@user-lb9oq9up1u
@user-lb9oq9up1u 4 месяца назад
Объясни пожалуйста как ты конфигурационные файлы удалил, перед тем как свой создал?
@front_interviews
@front_interviews 5 месяцев назад
Благодарю =)
@narwhal6422
@narwhal6422 3 месяца назад
Неожиданно топ контент😮
@darktmdarkness6952
@darktmdarkness6952 4 месяца назад
по поводу настройки сервера, есть небольшое замечание: еще для повышения безопасности меняют порт подключения к ssh с 22 на какой-нибудь 22202, и врубают фаервол и блочат все порты кроме ssh, http, https. Что дополнительно повышает устойчивость сервера к взлому.
@kirill_prog
@kirill_prog 4 месяца назад
Как же это круто! Прошу не останавливайся! Сделай бусти для донатов.
@paromovevg
@paromovevg 4 месяца назад
Сделал) boosty.to/paromov_evg/donate
@nainkanal3979
@nainkanal3979 5 месяцев назад
Очень крутой стек! Евгений, как часто будут выходить видео с этим курсом?
@paromovevg
@paromovevg 5 месяцев назад
Ближайшее время только такие видео и будут выходить. Где то раз в 1.5 - 2 недели
@alexdenuke
@alexdenuke 3 месяца назад
Автору спасибо, но было упущено про то, что линю надо обновить глобально
@user-yl5kn9gq4p
@user-yl5kn9gq4p Месяц назад
Привет молодец продолжай в том же духе😎
@neotom8653
@neotom8653 5 месяцев назад
Очень качественно
@igor5379
@igor5379 5 месяцев назад
никто из хитхаба секреты не сможет достать, КРОМЕ самого гидхаб)))
@ringnull
@ringnull 5 месяцев назад
Когда следующий видос ждать?
@user-xs2dx2mh3f
@user-xs2dx2mh3f 4 месяца назад
Крутейшее видео, спасибо. Очень ждал подобное. Вопрос по поводу базы: в чём основная мотивация заказа отдельной базы (не развёртывание внутри виртуального сервера)? Ведь за неё нужно платить отдельно. Это связано именно с удобной реализацией бэкапов? Или есть ещё какие-то существенные причины, может это более безопаснее и т.д?
@darktmdarkness6952
@darktmdarkness6952 4 месяца назад
1. настройки. Если вы покупаете вот такую базу у сервиса, она уже минимально настроена под железо и ресурсы сервера и вам ничего делать не нужно. Максимум, добавить в конфиг, какие-то свои настройки специфичные для вашего продукта и приложения. Если вы ставите базу просто рядом, то все настройки должны выполнять сами. И если с мускулом это проблема минимальна, то постгру придется настраивать под ресурсы которые прокинуты, например, в тот же докер, под железо и т.д. 2. up-time. В случае покупки у сервиса сервера бд, в стоимость входит администрирование и поддержка работы базы, самим хостером. Т.е. следить за базой и её безопасностью, нужно им. Если вы ставите рядом, то делать это нужно вам. Например, в случае постгры, собирать логи и метрики, смотреть за наполнением виртуальных таблиц и выполнением auto-vacuum. Если данные в auto-vacuum застряли, самому его выполнять и т.д. 3. производительность. Ваш сервис, это не всегда полтора пользователя в сутки, и может иметь высокую нагрузку на базу, как на запись, так и на чтение, требовать репликации и настройки кластеров, репликаций, регионнальности и много чего еще. Тогда тоже предпочтительнее базу выносить на отдельный сервер. И в не сложных случаях, так же проще скинуть все это на сервис, взяв у них услугу, чем нанимать команду девопсов и датабейз инженеров, или самому во всем этом разбираться.
@user-xs2dx2mh3f
@user-xs2dx2mh3f 4 месяца назад
@@darktmdarkness6952 спасибо за развёрнутый ответ. Очень интересно
@user-sh3dt6dy8p
@user-sh3dt6dy8p 5 месяцев назад
если использовать ufw вместе с doker, то внешние порты для докера не блокируются (вроде), надо дополнительно шаманить
@lepreclown2180
@lepreclown2180 5 месяцев назад
Подскажите пожалуйста, я ведь правильно понял, что используем prisma, локальную БД и напрямую к ней конектимся, только потому что нет отдельного backend. То есть если бы у нас был в реальном проекте backend(python) к примеру, то мы бы просто по API запросы делали?
@paromovevg
@paromovevg 5 месяцев назад
В более типичных проектах, да запросы просто шли бы к бекенду. Но тут всё же дальше будет больше отличий. Так как из за fullstack природы этого приложения, будет достаточно много бизнес логики, которую мы будем менеджить
@kixxgopro
@kixxgopro 11 дней назад
топ
@katada
@katada 5 месяцев назад
Круто!
@imthebest8000
@imthebest8000 Месяц назад
хм, а стоит добавлять docker? Или это уже лишнее?
@CJIu3eHb
@CJIu3eHb 5 месяцев назад
Тоже не получилось с фингерпринтом у appleboy/ssh-action, уж и по их мануалу получал отпечаток - глухо. Но оставил без отпечатка пока, т.к. неизвестно, что хуже в таком тонком деле, как безопасность - широко известный пакет с поломанным отпечатком или какой-то малораспространенный D3rHase/ssh-command-action с отпечатком. Кстати, пошарился чуть по другим ssh action - так далеко не у всех проверка отпечатков есть.
@1982RUFF
@1982RUFF 5 месяцев назад
Евгений, спасибо за отличное видео! Очень полезно и информация очень важная... Есть вопрос по поводу VDS сервера - какие должны быть требования под next с размещением небольшого и-магазина? Я взял на нетангелах 4 ядра и 4гб NVMе диск на 10гб - но после деплоя постоянные глюки и pm2 вылетает постоянно.. (( а если брать больше сервер - стоимость возрастает прилично... спасибо заранее за ответ!
@paromovevg
@paromovevg 5 месяцев назад
Тут нужно смотреть за мониторами, что не так. Может нагрузка большая и тут уже ничего не сделаешь придётся увеличивать машину, а может просто где то утечка памяти и он периодически отваливается
@1982RUFF
@1982RUFF 4 месяца назад
Ну вроде как проблема была в хостинге... в последнее время что то меняю на сайте и билдю повторно - вроде как работает нормально и не виснет как раньше было) @@maks2
@Mikalai-yc7yy
@Mikalai-yc7yy 5 месяцев назад
🔥🔥🔥🔥🔥🔥
@alhongelios53
@alhongelios53 3 месяца назад
небольшое уточнение по pm2 если прописать просто npx pm2 startup то при перезапуске сервака pm2 не стартует надо указывать еще название ОС то есть писать npx pm2 startup ubuntu
@egrpavlov2694
@egrpavlov2694 2 месяца назад
В видео немного перепутан алгоритм key-аутентификация. С помощью приватного ключа данные расшифровываются, а публичным шифруются
@abdurahmonvahobov8684
@abdurahmonvahobov8684 5 месяцев назад
👍
@plexterq3
@plexterq3 5 месяцев назад
Не пробовали использовать next-safe-action? Она позволит не писать код для валидации, просто передавая в action схему zod. Также там встроен враппер для обработки ошибок. И мы, написав свой слой ошибок, например ActionError, сможем в экшенах только этот тип ошибок передавать на клиент для toast. Ну и также позволит, например писать свой action, например authAction и тогда не надо будет в каждом action проверять авторизацию где она нужна. А ну и также генерит useAction, который как в react-query имеет onSuccuess, onError итд
@Selieznov
@Selieznov 5 месяцев назад
Не дума делать не только миграцию бд, а и самому?)
@grigodoes
@grigodoes 5 месяцев назад
Крайне полезная информация) спасибо Если создашь boosty с меня моментальная подписка!)
@user-ke4cy3cl2s
@user-ke4cy3cl2s 4 месяца назад
сделай курс по docker
@tahrizade
@tahrizade 4 месяца назад
а как ты монтируешь это видое ? это эже 4 часа и сколько времени уходит на скачивание в youtube ???
@paromovevg
@paromovevg 4 месяца назад
Времени уходит дохера. А так монтирую по частям. По факту тайм коды, это как раз части видоска которые я отдельно монтировал
@tahrizade
@tahrizade 4 месяца назад
@@paromovevg да тоже самое . думал есть какой-то лайф хак ))) тебя тогда желаю удачи чувак :) за видос спасибо
@JJohnson-fy9uz
@JJohnson-fy9uz 3 месяца назад
А почему pm2, а не докер?
@r0mm4k
@r0mm4k 5 месяцев назад
Привет. Как на счет того, чтобы в докер все это завернуть?
@paromovevg
@paromovevg 5 месяцев назад
Вообще хочется эту тему немного оттянуть. Next.js Плохо в докер заворачивается, так как для сборки нужно подключение к базе данных + все переменные окружения должны быть переданные во время билда. Это всё можно реализовать, но это немного концепции докера противоречит. +Менеджмент имеджей на vps не очень приятная штука (надо придумывать механизм всё время старые чистить) Рано или поздно в любом случае в докер проще уйти, но я оттяну немного этот момент
@yakub8798
@yakub8798 4 месяца назад
привет подскажите пж как получить доступ к 3 видео из плейлиста ?
@paromovevg
@paromovevg 4 месяца назад
Третье видео завтра выйдет
@yakub8798
@yakub8798 4 месяца назад
@@paromovevg понял, спасибо тебе за контент , очень нравятся твои уроки !
@alex91073
@alex91073 5 месяцев назад
Всем привет! благодарю Евгения за видео. у меня возникла проблема, когда гитхаб пытается подключиться к vps. может кто-нибудь помочь советом, как решить задачу? >> Public ssh fingerprint found, man-in-the-middle protection enabled. No ED25519 host key is known for [***]:*** and you have requested strict checking. Host key verification failed.
@xxcrypt234
@xxcrypt234 4 месяца назад
Гигачад
@1nightstarlight3
@1nightstarlight3 5 месяцев назад
Царский подгон, выходные уже удались
@deantek
@deantek 4 месяца назад
смотрю эту серию видосов, потому что боюсь завалить испыталку в банке, до этого 4 года на галерах греб, получил оффер в хорошую компанию, а теперь неуверенность меня съедает :`(
@ringnull
@ringnull 5 месяцев назад
1:39:39 это не синглтон, ты каждый раз при импорте получишь разные объекты
@wolfern5449
@wolfern5449 4 месяца назад
А где продолжение, автор?(
@paromovevg
@paromovevg 4 месяца назад
Уже на канале)
@izzy7541
@izzy7541 5 месяцев назад
На данном этапе, пока проект ещё сырой, тебе вообще юнит тесты не нужны, в них нет никакой практической пользы, только время потратишь. Пиши только е2е пока не сделаешь mvp продукт который будет работать. Дальше уже можешь по этапно внедрять юнит тесты когда они будут необходимы. А то тестировать детали реализации это очень плохо, так делать не надо
@paromovevg
@paromovevg 5 месяцев назад
Полностью отрицать юниты точно не стоит, они очень хорошо работают в "сложных" местах. В этом проекте такие будут, так что я решил их здесь использовать Но всё покрывать ими мы конечно не будем
@izzy7541
@izzy7541 5 месяцев назад
@@paromovevg Конечно, юниты местами нужны. Но большинство почему то тестируют выполнение кода, мокая каждый чих, забывая что сценарий теста должнен выполняться от лица пользователя
@SuperWhiteskull
@SuperWhiteskull 4 месяца назад
@@izzy7541сценарий теста от пользователя напишет тестировщик, а юнит тесты выполняют другую функцию
@denispepper2830
@denispepper2830 5 месяцев назад
fsd - это кринж
@rustamakhmetyanov4404
@rustamakhmetyanov4404 5 месяцев назад
ну у сбер с вами не согласится)) у них в вакансиях просят его
@Lear-fe6se
@Lear-fe6se 5 месяцев назад
можете предложить альтернативы?
@modusvivaldi7701
@modusvivaldi7701 3 месяца назад
@denispepper2830 Расскажешь, почему кринж?
Далее
CI CD наглядные примеры
22:08
Просмотров 267 тыс.
Все мы немного Адриана 😂😂😂
00:11
What’s your charging level??
0:14
Просмотров 7 млн
iphone fold ? #spongebob #spongebobsquarepants
0:15
Просмотров 201 тыс.
как спасти усилитель?
0:35
Просмотров 507 тыс.