Автор курса отдаёт платформе треть выручки: свои уроки на своём сервере
Продали курс на маркетплейсе — и треть суммы сразу ушла площадке, ещё и ученик формально "принадлежит" не вам, а сервису. Если вы записываете уроки сами, сами их продвигаете и сами отвечаете на вопросы в комментариях, а платформа только даёт витрину и берёт за это заметную часть каждой продажи — это разумно пересчитать. Ниже — рабочая схема, как перенести уроки на собственный сервер: без обещаний "легко и бесплатно", с честным разбором, где будет сложнее, чем на маркетплейсе, и где вы наконец получите то, чего там не было — прямой контакт с учеником.
Содержание
Треть — это только видимая часть потери
Комиссия — самая заметная строка в отчёте площадки, но не единственная цена вопроса. У маркетплейса курсов вы арендуете не только хостинг видео, вы арендуете отношения с учеником. Площадка решает, как выглядит карточка курса, может менять алгоритм выдачи так, что вчерашний бестселлер завтра не показывается новым посетителям, может вводить свои акции и скидки без вашего согласия, потому что коммерческая политика — её, не ваша. Переписка с учеником чаще всего тоже идёт через внутренний чат платформы: у вас нет его почты, нет номера телефона, нет возможности написать напрямую, если площадка решит закрыть ваш аккаунт — а такое случается из-за спорных модерационных решений, блокировки платежа или просто смены правил.
Отдельная проблема — данные. Вы не видите, сколько на самом деле человек досматривает урок, где он останавливается, какие вопросы задаёт чаще всего вне комментариев под уроком. Площадка эту аналитику либо не показывает вовсе, либо показывает урезанную версию, потому что подробная статистика — это тоже её актив, а не ваш.
Это не значит, что маркетплейс — зло. Для старта курса, для первой сотни продаж, для проверки темы площадка с готовой аудиторией часто быстрее и дешевле, чем самостоятельная разработка. Разговор в этой статье — про следующий шаг: когда курс уже приносит стабильный поток учеников и комиссия начинает ощущаться не как плата за услугу, а как утечка, которую пора закрыть.
Что реально нужно для собственной системы уроков
Не нужно нанимать команду и писать LMS с нуля — для среднего курса хватает четырёх компонентов, и три из них можно закрыть готовыми инструментами за один вечер настройки.
- Хранилище видео — где физически лежат файлы уроков.
- Контроль доступа — механизм, который отдаёт урок только тому, кто его купил, и не отдаёт всем остальным.
- Приём оплаты — форма или кнопка, которая записывает в базу "этот человек оплатил этот курс".
- Канал связи с учеником — почта, телеграм-бот или что угодно, что принадлежит вам, а не площадке.
Технически всё это можно собрать на одном недорогом VPS: веб-сервер (nginx или Caddy) отдаёт статику и защищённое видео, небольшое приложение (Node.js, Python/FastAPI или даже готовая CMS с плагином курсов) хранит список учеников и их доступов, база данных — PostgreSQL или SQLite для небольшого потока — держит записи о покупках. Писать LMS с нуля не обязательно: для WordPress есть плагины курсов уровня LearnDash и аналогов, есть Moodle как полноценная (хоть и тяжеловесная) платформа, и в половине случаев проще взять готовое решение и адаптировать шаблон, чем писать собственный личный кабинет ученика. Разберём по частям — от простого к сложному.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверГде хранить видео и как раздавать его без вечных утечек
Первый вопрос, который встаёт сразу: если положить видео-файлы в обычную папку на сервере, любой, кто узнает прямую ссылку, сможет её переслать — и урок разойдётся мимо оплаты. Полностью закрыть эту дыру не может ни одна платформа, включая крупные маркетплейсы: экран всегда можно записать. Но можно убрать самый частый и глупый способ утечки — постоянную прямую ссылку на файл, которая гуляет по чатам месяцами.
Рабочий вариант для nginx — модуль secure_link, который генерирует временную ссылку с ограниченным сроком жизни:
location /lessons/ {
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$uri secret_key_here";
if ($secure_link = "") {
return 403;
}
if ($secure_link = "0") {
return 410;
}
root /var/www/course-videos;
}
Ваше приложение при выдаче доступа считает md5-хэш от пути к файлу, времени истечения и секретного ключа, подставляет его в ссылку — и она перестаёт работать через заданное время (например, час — этого достаточно, чтобы посмотреть урок, но мало, чтобы ссылка успела разойтись далеко). Похожий принцип использует связка "видеоуроки с контролем доступа" на арендованном сервере — если интересна более развёрнутая механика привязки доступа к конкретному ученику, стоит посмотреть материал про видеоуроки с контролем доступа, там разобран похожий сценарий для тренера, который ведёт группы онлайн.
Второй вариант — не хранить видео прямо на диске веб-сервера, а вынести в S3-совместимое хранилище (например, MinIO, поднятое на этом же или на отдельном сервере) и отдавать доступ через presigned URL — временную подписанную ссылку, которую генерирует хранилище само:
mc alias set course-storage https://storage.example.com ACCESS_KEY SECRET_KEY
mc share download course-storage/lessons/module3-lesson2.mp4 --expire=1h
Плюс такого подхода — вы отделяете хранение от раздачи, что упрощает бэкапы и масштабирование, если курсов и уроков становится много. Минус — лишний компонент в инфраструктуре, который тоже нужно поддерживать. Для одного-двух курсов с несколькими десятками уроков секрет-ссылок в nginx обычно достаточно; про сам подход с собственным S3-хранилищем есть отдельный разбор — S3-совместимое хранилище у себя.
Что касается формата видео — конвертировать всё в HLS (нарезку на сегменты с плейлистом) имеет смысл, если у вас действительно много одновременных просмотров или вы хотите адаптивное качество под разную скорость интернета ученика. Для курса с сотней-другой активных учеников обычный mp4 с secure_link отрабатывает нормально, и не стоит усложнять инфраструктуру ради проблемы, которой пока нет.
Доступ ученика: от покупки до просмотра урока
Логика простая, но важно продумать её сразу, а не на ходу. Три таблицы обычно достаточно:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
telegram_id BIGINT,
created_at TIMESTAMP DEFAULT now()
);
CREATE TABLE courses (
id SERIAL PRIMARY KEY,
slug TEXT UNIQUE NOT NULL,
title TEXT NOT NULL
);
CREATE TABLE access (
student_id INT REFERENCES students(id),
course_id INT REFERENCES courses(id),
granted_at TIMESTAMP DEFAULT now(),
expires_at TIMESTAMP,
PRIMARY KEY (student_id, course_id)
);
Поле expires_at пригодится, даже если курс продаётся с "пожизненным" доступом — на практике это часто означает "доступ на весь период, пока актуальна программа", и удобно иметь техническую возможность его продлевать или, наоборот, ограничивать без правки кода.
Дальше — простая проверка при заходе на страницу урока (пример на FastAPI):
@app.get("/lesson/{course_slug}/{lesson_id}")
async def get_lesson(course_slug: str, lesson_id: int, student=Depends(get_current_student)):
access = await db.fetch_one(
"SELECT * FROM access a JOIN courses c ON a.course_id = c.id "
"WHERE c.slug = :slug AND a.student_id = :sid "
"AND (a.expires_at IS NULL OR a.expires_at > now())",
{"slug": course_slug, "sid": student.id}
)
if not access:
raise HTTPException(403, "Нет доступа к этому курсу")
signed_url = generate_signed_url(course_slug, lesson_id, ttl=3600)
return {"video_url": signed_url}
Авторизацию ученика проще всего делать не паролем (его забывают, приходится восстанавливать), а магической ссылкой на почту или кодом в телеграм-бота — меньше нагрузки на поддержку. Если писать всё это с нуля кажется избыточным для одного курса — это честная оценка, и в таком случае разумнее взять готовый плагин курсов для WordPress или Moodle: обе системы уже решают задачи "кто купил — тот видит", просто ценой более тяжёлого стека на сервере.
Оплата и прямая связь с учеником — то, чего не было на площадке
Здесь — главное практическое преимущество перехода на свой сервер, а не только экономия на комиссии. На маркетплейсе вы почти никогда не получаете email или телефон ученика напрямую — вся коммуникация идёт через внутренний чат площадки. На собственной системе продаж email или телеграм ученика — обязательное поле формы оплаты, и он ваш с первого дня: можно написать про новый модуль курса, про распродажу смежного продукта, про вебинар — без посредника и без риска, что аккаунт с накопленной базой учеников однажды заблокируют.
Приём оплаты для российской аудитории обычно закрывается одним из платёжных агрегаторов с эквайрингом для физлиц или ИП — конкретный выбор зависит от вашей юридической формы и оценивать проценты эквайера стоит по актуальным тарифам самого агрегатора на момент подключения, они меняются, и приводить здесь точную цифру было бы нечестно. Для зарубежной части аудитории или как дополнительный вариант имеет смысл держать приём оплаты криптовалютой — по крайней мере как резервный канал, если основной эквайринг временно недоступен. Сама аренда сервера под эту систему тоже может оплачиваться картой или криптой — если нужен обзор способов, есть разбор как оплатить сервер в России из России картой и криптой.
После оплаты — вебхук от платёжной системы, который создаёт запись в таблице access, и автоматическое письмо ученику со ссылкой на личный кабинет. Дальше — рассылка. Не обязательно строить сложную CRM: простой список подписчиков с сегментацией "купил курс X" / "смотрел бесплатный урок, но не купил" уже даёт возможность делать точечные предложения, которых на площадке у вас просто не было бы технически.
Технический фундамент: сервер, домен, SSL, бэкапы
Для курса на несколько десятков уроков с умеренным потоком одновременных просмотров обычно достаточно небольшого VPS — 2-4 виртуальных ядра, несколько гигабайт оперативной памяти, диска с запасом под весь объём видео плюс место под бэкапы. Точную конфигурацию под свою нагрузку правильнее считать по факту: сколько часов видео, какое разрешение, сколько человек может смотреть одновременно в пиковый вечер. Если курс растёт и просмотров становится действительно много, отдачу видео стоит вынести на отдельный сервер или подключить CDN перед ним, чтобы не упираться в канал одной машины.
Домен и SSL — обязательная база: без валидного сертификата браузер будет пугать ученика предупреждением, а сама ссылка на personal cabinet должна быть на своём домене, а не на IP-адресе, чтобы выглядеть надёжно. Проще всего поднять Caddy — он получает сертификат Let's Encrypt автоматически и не требует отдельной настройки certbot:
lessons.example.com {
reverse_proxy localhost:8000
}
Бэкапы — то, о чём на маркетплейсе вы вообще не думали (площадка сама отвечает за сохранность видео и базы учеников), а на своём сервере это становится вашей зоной ответственности. Минимум — ежедневный снапшот базы данных с покупками и доступами (это критичнее, чем сами видеофайлы: их в крайнем случае можно перезалить с исходников, а базу учеников — нет) и регулярный бэкап хранилища видео. BorgBackup с дедупликацией хорошо подходит для регулярных снапшотов без раздувания места на бэкап-сервере:
borg create --stats --progress \
/mnt/backup-repo::lessons-$(date +%Y-%m-%d) \
/var/www/course-videos /var/lib/postgresql/data
Держите хотя бы одну копию бэкапа не на том же сервере, где лежат исходные данные — если сервер выйдет из строя целиком, локальный бэкап на нём не поможет.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Не проще ли остаться на площадке, если курс небольшой и продаж немного?
Для одного-двух курсов и нерегулярных продаж миграция может не окупить время на настройку — площадка в этом случае действительно проще. Разговор про свой сервер имеет смысл, когда продажи стабильны и комиссия за месяц ощутимо превышает стоимость аренды сервера и время на поддержку системы.
Что мешает ученику просто скачать урок и распространить его дальше?
Ничего не мешает полностью — как и на любой другой платформе, включая крупные маркетплейсы. Временные подписанные ссылки и привязка доступа к аккаунту убирают самый массовый и ленивый способ утечки — постоянную ссылку, гуляющую по открытым чатам, но не защищают от целенаправленной записи экрана.
Нужно ли переносить все старые курсы сразу?
Не обязательно. Многие переносят постепенно: новые курсы сразу продают через свою систему, а старые донашивают на площадке, пока текущий поток продаж по ним не иссякнет — так меньше риск потерять доступ к уже наработанной аудитории маркетплейса в переходный период.
Что делать с отзывами и рейтингом, накопленным на площадке?
Они остаются на площадке и не переносятся технически. Если рейтинг и отзывы — значимая часть продающей воронки курса, есть смысл держать присутствие на площадке параллельно как источник новых учеников, а свою систему использовать для дальнейшей работы с уже купившими.
Сколько времени в среднем занимает такая настройка с нуля?
Зависит от того, берёте ли вы готовый плагин курсов для CMS или пишете свой личный кабинет. С готовым решением базовую версию — сервер, домен, SSL, защищённая раздача видео и приём оплаты — реально собрать за несколько дней; собственная разработка личного кабинета и логики доступа занимает заметно дольше и оправдана, только если готовые решения не покрывают ваш конкретный сценарий.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →