MyPrepod — крупнейший портал отзывов о преподавателях российских ВУЗов. Он стал таким не только засчет того, что даже на момент MVP 2017 года он был UX‑удобнее для студентов, чем СтудИзба или professorrating, но и засчет полной анонимности. Можно написать отзыв о преподе с умного холодильника Samsung, без авторизаций и пред‑модерации. Сказать все, что бы хотел сказать, не опасаясь «пометочки» от преподавателя около твоей фамилии, и уже спокойным пойти на пересдачу.
Поскольку все это, опять же, анонимно и модерируется после отправки(в том числе и добавления преподавателей), проблем в 2026 с этим куча. Мы тут не затронем конкретные обходы законов разных стран, но я покажу, как именно мы написали вещь, которая адаптируется к любым действиям людей, которым не очень нравится знать, что студенты могут не только восхищаться и заискивать, лишь бы получить зачет. И что вне ВУЗа ты обычный человек, абсолютно равный тем, что учатся в твоей группе.
Опишу как TeamLead разработки этого проекта: как делать неудобный кому‑то продукт
Начнем с очевидного:
Было MVP 2017 года, которое невероятно разрослось. Чтобы его поддерживать, нужны деньги на разработку. Деньги получать можно только с рекламы. Но рекламодатели не очень хотят рекламироваться на MVP 2017 года, а без поддержки этого сама суть анонимной платформы ставится под угрозу. С каждым днем трафик от отсутствия поддержки будет только падать.
Посмотрите на тот же двач, его давно обновлять пора. На нем уже сидеть больно.
Дизайн — половина беды. Бедняга грузился по 10–15 секунд, не открывался на некоторых устройствах в принципе. Его написали на сухом PHP 5.4, в а качестве админки использовался чудесный инструмент:
mysql -u root
При всем этом популярность и SEO вес он накапливал 10 лет, пожирая сайты вузов и выплевывая ниже себя в ответ на запрос ФИО препода. Хотя старая ссылка была буквально такой:
/index.php?page=res&res=6717
Нас как раз и позвали разработать новый дизайн, грамотно использовать SEO потенциал и ускорить загрузку с текущей огромной базой.
Стек:
Laravel 13 (+MoonShine Admin Panel), Vue 3, Redis, Nginx, MySQL 8, и все это в Docker.
Дизайн:
Обновленная главная ниже:
Старались сохранить основную гамму, подобрать похожие шрифты, взяли схему разделов и структуру как у типичного форума. Главное, чтобы старый пользователь зашел на myprepod и сразу понял, что это все еще myprepod, а рекламодатель — что тут уже ничо так, прилично.
SEO:
Обсудим тут только главные для переноса такого большого проекта изменения, которые точно нельзя упустить. Для начала все старые имеющие вес ссылки закрыли 301 редиректом на новые, человеко‑понятные урлы.
Вместо:
/index.php?page=res&res=6717
Теперь «слаг-универа/имя-препода-айдишник»:
/msal/taylor-swift-1
В nginx мы ловим запрос на старый URL:
if ($arg_page = "res") {return 301 /legacy-tutor-redirect/$arg_res?;}
И кидаем его на разборку с внутренним router’ом Laravel:
Route::get('/legacy-tutor-redirect/{id}', function ($id) { $tutor = Tutor::findOrFail($id); if ($tutor) { return redirect()->route('tutors.show', [ 'university' => $tutor->university->slug, 'tutor' => $tutor->slug, ], 301); }});
Конечно, такой двойной редирект из Nginx в Ларку и потом на новую страницу препода мог потратить чуть больше краулингового бюджета, но других вариантов, если мы хотим по итогу получить нормальный слаг преподавателя — нет.
Далее исходя из уже готовых сущностей, по типу Преподаватель и Университет, сразу напрашивались страницы под запросы «Отзывы о преподавателях МГЮА», например.
Засеошилась она за счет большого веса главной, где ссылка на страницу всех ВУЗов и конкретного ВУЗа в частности, а также немного за счет ссылки на ВУЗ в карточке преподавателя.
Таким образом по всем ключевым запросом myprepod выходит либо первый, либо в числе первых на новых страницах.
Стоит ли говорить, что на старых страницах не было раньше ни микроразметки, ни семантики, ни даже description — не знаю. Думаю, это очевидно.
Подкапотка:
Вот тут и будет самое интересное. Суть в том, что раньше на myprepod регулярно прилетали жалобы. И, понятное дело, не на саму платформу в админку — а в РКН, напрямую на хостинги, Cloudflare и даже по GDPR(General Data Protection Regulation) в Европу.
Суть жалоб — распространение персональных данных, а также мясо, матюки и так далее по списку.
Я лично столкнулся с такими историями впервые. Никогда на мой сервис не было столько попыток обнулить его от разных контор и частных лиц. Но суть была такая: в любую секунду хостинг, домен, на котором висит myprepod, может быть заблочен, сайт перестанет работать, а данные будет уже не выкачать.
Для домена все просто — если заблокирует РКН, тут уже ничего ты особо не сделаешь. Поэтому мы это опустим.
Для хостинга — сложнее.
Обычно хосты предупреждают, мол, удаляйте страницу с обвинениями преподавателя в обнулении Кеннеди, либо в течение какого то времени мы отрубим вам услуги. Так, по крайней мере, делал Hetzner.
Но оттуда мы ушли на Hostinger, который просто в один прекрасный день прислал на обновленный майпрепод в 02:20 по МСК письмо:
Актуальную БД с него не достать, картинки преподов тоже. Хост просто уложился спать, а узнать мы об этом должны были через милое письмо, которое попало в рассылку.
Ну или по тому, что сайт не отвечает, а ты сидишь и гадаешь с потным лбом в 2 часа ночи, почему
Разумеется, для таких ситуаций придумали запасной VDS и Health‑чеки. Если хостинг выдает таймаут на подключение — перенаправляем на рабочий аппарат, который каждый день в момент ежедневного(а может и чаще) бекапа накатывает актуальные данные на себя.
Но учитывая скорость блокировок(на Hostinger пришла жалоба через сутки после запуска обновленного МП), желательно еще и иметь возможность развернуть вообще все с нуля и где угодно в любой момент времени. И на самом деле именно для этого в проекте тусуется Docker.
Не для микросервисов, поднятия контейнеров и прочей дево‑псины. В основном — для этого.
Одна команда docker compose buildи через 5 минут у тебя натянут готовый проект на сервер.
Итак, как настроить докер так, чтобы его реально можно было поднять одной командой в случае emergency. Очень просто — засунуть в docker nginx. Итого в нашем докере тусуются:
— Nginx, который сразу светит нужным 443 наружу
SSL решается через certbot‑контейнер с общим volume — сертификаты автоматически обновляются и Nginx их подхватывает без перезапуска
— Laravel 13
— MySQL 8
— Laravel‑Воркер для очередей
— Laravel‑Расписание для обновления кешей
— Redis, через который и кешируем главную с последними отзывами и преподами
По метрикам получился рост среднего времени на сайте с 2 минут до 4, процент отказов упал до 20, количество посетителей в день увеличилось вдвое, с 2 тысяч до 4.
Метрика публичная, welcome
Итого весь проект переезжает в любое удобное место за одну команду и 5 минут времени.
Держа домен на Cloudflare — мы получаем обновление DNS буквально за несколько минут, так что так кочевать в случае чего — вполне себе вариант.
Именно в такой сборке получалась сегодняшняя стрессоустойчивая модель анонимного портала. Грубо говоря, «поймай меня, если сможешь»
Итого:
Остаться анонимной платформой стало сложнее. Рекламодателей нет, при этом аудитория хочет уровень, за который надо платить. Сами слои приложения — домен, хостинг, бэкапы, Docker. Каждый слой сейчас можно выбить — поэтому надо искать пути их быстро заменить. В 2026 году на эти проблемы накладываются ограничения, которые через пару лет не оставят шанса «случайно кого то обидеть, написав под фотографией плохую фразочку»
ссылка на оригинал статьи https://habr.com/ru/articles/1045024/