Раздача видео и больших файлов в Nginx: что выбрать
Прямая раздача, проксирование, X-Accel-Redirect и объектное хранилище решают разные задачи. Сравниваем нагрузку, контроль доступа, докачку и стоимость, чтобы выбрать схему для Nginx без лишнего усложнения.

Если Nginx отдаёт видео через приложение, каждый просмотр занимает соединение и ресурсы backend-сервера. Если открыть файл напрямую, теряется контроль доступа. Для больших файлов выбор между статической раздачей, proxy_pass, X-Accel-Redirect и объектным хранилищем влияет на докачку, перемотку, нагрузку на диск и счёт за трафик. Ниже — практическое сравнение для Nginx 1.24+ с конфигурациями, которые можно адаптировать под ваш проект.
Что именно нужно раздавать
Сначала разделите файлы по сценарию. Публичный архив документов и защищённое видео для авторизованных пользователей не должны обслуживаться одной и той же схемой.
- Публичные файлы. Их можно отдавать напрямую из Nginx или CDN. Проверка прав не нужна.
- Файлы с доступом по аккаунту. Приложение должно решить, можно ли скачивать объект, но само передавать байты ему необязательно.
- Видео с перемоткой. Клиенту нужны диапазонные запросы HTTP Range, иначе браузер может скачивать ролик целиком перед воспроизведением нужного фрагмента.
- Очень большие или редко используемые объекты. Их часто выгоднее хранить в объектном хранилище, а Nginx оставить точкой входа или вообще убрать из цепочки.
Range-запрос[1] просит не весь файл, а определённый диапазон байтов. Заголовок ответа Content-Range сообщает клиенту, какую часть он получил.
Приложение должно принимать решение о доступе, но не обязано самостоятельно пересылать гигабайты данных.
Четыре схемы и их цена
| Схема | Когда подходит | Что выигрываете | Чем платите |
|---|---|---|---|
| Статическая раздача Nginx | Публичные файлы на локальном диске | Минимум кода и задержек, поддержка Range | Нужны место на диске, резервирование и открытый URL |
proxy_pass к приложению | Backend уже является источником файлов | Простая интеграция с существующим сервисом | Backend и его сеть участвуют в каждой передаче |
X-Accel-Redirect | Нужна проверка прав перед отдачей | Приложение проверяет доступ, Nginx передаёт файл | Нужны внутренний location и согласованные пути |
| Объектное хранилище или CDN | Много трафика, несколько серверов, большие объёмы | Масштабирование и разгрузка локальной инфраструктуры | Оплата хранения и исходящего трафика, настройка подписанных ссылок |
Главная ошибка — выбирать proxy_pass только потому, что файл уже возвращает приложение. Это работает на небольшом объёме, но при скачивании 5 ГБ backend держит соединение, а иногда ещё и читает файл через собственный код. Передача байтов становится частью нагрузки приложения.
Вариант 1. Прямая раздача с диска
Для публичных MP4, ZIP и ISO достаточно отдельного location. Пример рассчитан на Nginx 1.24+.
server {
listen 443 ssl;
server_name files.example.test;
location /downloads/ {
alias /srv/files/;
sendfile on;
tcp_nopush on;
add_header Accept-Ranges bytes always;
add_header Cache-Control "public, max-age=3600";
}
}
Здесь URL /downloads/video.mp4 соответствует файлу /srv/files/video.mp4. Директива alias подставляет указанный каталог, поэтому завершающий слеш в обоих путях важен.
Проверяйте результат запросом заголовков и диапазона. В ответе должны быть успешный статус, корректный Content-Length, а при диапазонном запросе — статус 206 Partial Content и Content-Range.
curl -I https://files.example.test/downloads/video.mp4
curl -i -H "Range: bytes=0-1048575" https://files.example.test/downloads/video.mp4 -o /dev/null
sendfile on позволяет Nginx передавать данные эффективнее, используя возможности операционной системы. Это не отменяет узкие места: медленный диск, файловую систему, сетевой канал и лимиты виртуальной машины.
Вариант 2. Проксирование через приложение
Схема с proxy_pass удобна, если файл действительно генерируется на лету или лежит только в сервисе, который уже умеет его отдавать.
location /media/ {
proxy_pass http://media_backend;
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off;
proxy_read_timeout 1h;
}
Отключение буферизации не ускоряет приложение. Оно уменьшает вероятность того, что Nginx будет сначала складывать ответ backend во временные буферы или файлы, а потом отдавать его клиенту. Точный эффект зависит от размера ответа и поведения upstream.
Перед использованием проверьте, что само приложение корректно обрабатывает Range, возвращает 206 и не выставляет неправильный Content-Length. Если backend всегда отвечает полным файлом, перемотка и докачка могут работать плохо.
Вариант 3. X-Accel-Redirect: проверка в приложении, передача в Nginx
Это обычно лучший компромисс для закрытых файлов на локальном диске. Приложение проверяет пользователя и возвращает не содержимое файла, а специальный заголовок. Nginx затем обслуживает файл сам.
В конфигурации создайте внутренний маршрут. Запросить его напрямую клиент не сможет: директива internal запрещает внешнее обращение.
location /protected-files/ {
internal;
alias /srv/private-files/;
sendfile on;
add_header Accept-Ranges bytes always;
}
После успешной проверки приложение должно вернуть заголовок вида:
X-Accel-Redirect: /protected-files/report-2025.pdf
Путь в заголовке не должен собираться из непроверенного пользовательского ввода. Храните в базе идентификатор файла и его безопасное внутреннее имя, а не принимайте произвольный путь вроде ../../etc/passwd. Приложение может добавить имя для скачивания через Content-Disposition, но значение нужно формировать с учётом правил вашего фреймворка и кодировки.
Проверка успешна, если авторизованный пользователь получает файл и диапазонный запрос, а прямой запрос к /protected-files/... возвращает ошибку доступа. Конкретный статус зависит от остальной конфигурации Nginx.
Вариант 4. Объектное хранилище и CDN
Когда файлы лежат на нескольких серверах или трафик растёт быстрее дисковой подсистемы, локальная раздача перестаёт быть самым простым решением. Объектное хранилище отделяет хранение от веб-серверов, а CDN может отдавать популярные диапазоны из ближайшей точки.
Для закрытого объекта приложение обычно создаёт временную подписанную ссылку или проксирует запрос через свой домен. Название механизма, срок действия и набор подписываемых параметров зависят от конкретного хранилища, поэтому их нужно брать из официальной документации выбранного провайдера.
Не прячьте секретные ключи в конфигурации, доступной веб-серверу или репозиторию. На практике также проверяют:
- поддержку Range и корректный ответ на диапазонный запрос;
- поведение ссылки после истечения срока действия;
- стоимость исходящего трафика и запросов;
- совместимость CDN с большими объектами и частичными ответами;
- время удаления объекта и наличие версий или резервных копий.
Что выбрать в конкретном проекте
Публичный каталог или архив
Начните со статической раздачи Nginx. Добавьте CDN, когда канал сервера или география пользователей становятся ограничением. Не подключайте приложение к каждому скачиванию без необходимости: оно не добавит ценности, если файл открыт для всех.
Закрытые документы и видео
Если файлы находятся на локальном диске, используйте X-Accel-Redirect. Приложение отвечает за аутентификацию, срок доступа и журналирование, а Nginx — за поток байтов. Это снижает нагрузку на backend по сравнению с прямым проксированием.
Большая библиотека и несколько серверов
Выносите объекты в хранилище. Локальные копии можно оставить только для горячего контента, если это оправдано измерениями. Считайте не только гигабайты хранения, но и исходящий трафик: именно он часто становится крупнейшей статьёй расходов.
Видео: перемотка, MP4 и HLS
Для обычного прогрессивного скачивания MP4 достаточно корректной поддержки диапазонов. Если пользователь должен начинать воспроизведение с произвольного времени, метаданные MP4 должны находиться в доступной для такого сценария части файла. Nginx может использовать модуль ngx_http_mp4_module, но он должен быть включён в сборку, а сам модуль не заменяет видеоконвертацию.
Проверить наличие модуля можно через вывод nginx -V. Если в вашей сборке модуля нет, не добавляйте директиву mp4 вслепую: Nginx завершит проверку конфигурации с ошибкой «unknown directive».
Для адаптивного вещания применяют HLS или MPEG-DASH: исходный ролик заранее разбивается на сегменты и манифест. Это отдельная архитектура, а не просто ещё одна настройка location. Транскодирование, DRM и упаковка видео здесь не рассматриваются.
Что ломается чаще всего
- Всегда возвращается 200 вместо 206. Проверьте, кто отвечает за
Range: Nginx, upstream, CDN или объектное хранилище. - Видео начинается только после полной загрузки. Проверьте диапазонные ответы, заголовки и расположение метаданных MP4.
- Закрытый файл доступен по прямому URL. Проверьте, что защищённый
locationпомечен какinternal, а публичный каталог не пересекается с ним. - После изменения конфигурации Nginx не запускается. Выполните
nginx -tи смотрите на первую ошибку, а не на последующие сообщения systemd. - Диск заполнен временными файлами. Проверьте буферизацию proxy, место в файловой системе и логи. Не удаляйте каталоги Nginx вслепую, пока не определили, какой процесс держит файлы.
Что делать дальше
Сначала замерьте реальный сценарий: размер объекта, число одновременных скачиваний, долю диапазонных запросов, скорость диска, загрузку CPU и сетевой канал. Затем выберите минимальную схему: публичный файл — статическая раздача, закрытый локальный файл — X-Accel-Redirect, масштабируемая библиотека — объектное хранилище и CDN.
После внедрения смотрите на коды 200, 206, 4xx и 5xx, время передачи, размер ответа и заполнение диска. Отдельно проверьте возобновление прерванной загрузки и доступ без авторизации. Именно эти проверки покажут, работает ли выбранная схема в проде, а не только в браузере разработчика.
[1] Range-запрос — HTTP-запрос части ресурса по диапазону байтов; он нужен для докачки и перемотки больших файлов.
Задачи: математика, физика, химия: Разбор задачи по шагам с проверкой и похожей задачей
Спросить за 10 ₽Источники: Nginx HTTP Core Module: sendfile, alias и обработка диапазонов, Nginx ngx_http_mp4_module
Частые вопросы
Нужно ли использовать proxy_pass для всех видео?
Почему браузер не перематывает MP4?
Безопасен ли X-Accel-Redirect для закрытых файлов?
Что выбрать для файлов размером от нескольких гигабайт?
Нужен ли Nginx, если файлы уже находятся в объектном хранилище?
Что проверять после перехода в прод?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.