До основного вмісту

Віддача статики в Nginx: try_files, expires і sendfile

Nginx · 29.09.2026

Чому статику краще віддавати напряму

Картинки, CSS, JS і шрифти не потребують виконання PHP-коду, тому пропускати їх через PHP-FPM — марна витрата ресурсів. Nginx уміє віддавати файли з диска напряму, у рази швидше і з меншим навантаженням на сервер. Завдання адміністратора — правильно вказати Nginx, які шляхи обслуговувати напряму, а які передавати бекенду.

Як працює try_files

Директива try_files перевіряє файли та каталоги по порядку і віддає перший знайдений, а якщо нічого не знайдено — передає запит далі:

location / {
    root /var/www/example.com/public;
    try_files $uri $uri/ /index.php?$query_string;
}

Тут Nginx спершу шукає файл із точним іменем запиту, потім каталог із таким іменем, і лише якщо нічого не знайшлося — передає запит в index.php. Це стандартна схема для WordPress, Laravel і більшості сучасних PHP-застосунків.

Як віддавати статику окремим location

Для статичних файлів варто виділити окремий блок із власними налаштуваннями кешування:

location ~* \.(jpg|jpeg|png|gif|webp|svg|css|js|woff2?)$ {
    root /var/www/example.com/public;
    try_files $uri =404;
    expires 30d;
    add_header Cache-Control "public, immutable";
    access_log off;
}

Параметр access_log off для статики знижує навантаження на диск: немає сенсу писати в лог тисячі запитів картинок і скриптів.

Директиви кешування та швидкодії

ДирективаЗначенняЕфект
expires30d, 1yЗаголовок Cache-Control і Expires для браузера
sendfileonВіддача файлу через системний виклик sendfile, без копіювання в пам'ять Nginx
tcp_nopushonНадсилання заголовків і початку файлу одним TCP-пакетом
open_file_cachemax=1000 inactive=20sКеш дескрипторів файлів і метаданих, щоб не читати диск повторно

Директиви sendfile і tcp_nopush вмикають у секції http {} один раз — вони діють глобально і не потребують налаштування для кожного сайту.

Як налаштувати open_file_cache

На сайтах із великою кількістю дрібних файлів — іконки, аватари, мініатюри — корисно увімкнути кеш дескрипторів:

open_file_cache max=2000 inactive=30s;
open_file_cache_valid 60s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

Це зменшує кількість системних викликів open() і stat() для файлів, які запитують часто: Nginx зберігає їхні дескриптори в пам'яті замість повторного читання з диска.

Часті помилки при віддачі статики

Що найчастіше ламає роздачу статики:

  • занадто довгий expires для файлів без версіювання в імені — оновлений CSS не долетить до користувача
  • регулярний вираз у location без екранування крапки — збіжиться із зайвими шляхами
  • відсутність try_files $uri =404; — запит на неіснуючий файл піде в PHP-FPM даремно
  • root, вказаний у двох різних місцях конфігурації з різними шляхами — типова причина 404 на статиці

Підсумок

Чек-лист для швидкої віддачі статики:

  • винести статичні розширення в окремий location із try_files $uri =404;
  • задати expires від 30 днів і Cache-Control: immutable для файлів із версією в імені
  • увімкнути sendfile, tcp_nopush і open_file_cache у http {}
  • вимкнути access_log для статики, щоб не навантажувати диск

Після налаштування статики варто перевірити стиснення відповідей через gzip і Brotli і увімкнути підтримку HTTP/2 та HTTP/3 — разом із try_files і expires це дає основний приріст швидкості сайту.

← Назад до бази знань Поставити питання підтримці