Справочник

expires в nginx: как настроить кэш браузера

Директива expires добавляет к ответу заголовки Expires и Cache-Control: браузер сохраняет файл и до конца срока не запрашивает его заново. Ставят её для стилей, скриптов и картинок, а страницам HTML долгий срок не задают.

≈ 6 мин чтения
Содержание 10

Что сделать прямо сейчас

  1. Команды вводятся на сервере: подключитесь к нему по SSH ([как подключиться](/instrukcii/kak-podklyuchitsya-k-vps-po-ssh/)) и набирайте их в том же окне.
  2. Откройте файл сайта: sudo nano /etc/nginx/sites-available/example.com. Вместо example.com — имя файла вашего сайта: список покажет ls /etc/nginx/sites-enabled/. Если система спросит пароль, введите пароль своего пользователя на сервере. Символы при вводе не видны — наберите пароль и нажмите Enter.
  3. Найдите в файле строку root: Ctrl+W, слово root, Enter. Сразу после неё, внутри блока server, добавьте блок для стилей, скриптов и картинок.
  4. Сохраните файл — Ctrl+O, Enter, затем Ctrl+X — и проверьте настройки: sudo nginx -t. В ответе должны быть слова syntax is ok и test is successful. Тогда примените их: sudo systemctl reload nginx. Если команда ничего не ответила, настройки применены.
  5. Проверьте заголовки — как это сделать.

Если проверка нашла ошибку, nginx назовёт файл и номер строки, а сайт продолжит работать на старых настройках. Что значит сообщение — Все ошибки nginx.

Блок для стилей, скриптов и картинок

location ~* \.(css|js|png|jpe?g|webp|gif|svg|ico|woff2)$ {
    expires 30d;
}

Знак ~* значит: регулярное выражение без учёта регистра букв, подойдут и .PNG, и .png. Блок срабатывает на адреса, которые кончаются этими расширениями. 30d — 30 дней. Как nginx выбирает между этим блоком и location / — location в nginx.

Файлы в этом блоке nginx берёт из папки, указанной в root. Если файла нет, nginx ответит 404 и не передаст запрос ни в index.php, ни приложению.

Если картинки и стили отдаёт приложение через proxy_pass, а в папке из root их нет, этот блок не подойдёт: на них начнётся 404. Тогда напишите строку expires 30d; в том блоке location, через который идут эти файлы, например location /static/. В location / её не пишите — срок получат и страницы.

Если в файле уже есть блок location с регулярным выражением для этих расширений, второй не добавляйте — допишите expires в существующий. Из двух подходящих регулярных выражений nginx берёт первое по порядку в файле.

Что значат значения expires

СтрокаЧто получит браузер
expires 30d;Cache-Control: max-age=2592000 — 30 дней в секундах — и Expires с датой через 30 дней
expires 12h;Cache-Control: max-age=43200 — 12 часов
expires max;Cache-Control: max-age=315360000 — 10 лет — и Expires: Thu, 31 Dec 2037 23:55:55 GMT
expires 0;Cache-Control: max-age=0 — срок хранения ноль
expires -1;Cache-Control: no-cache и Expires в прошлом
expires epoch;Cache-Control: no-cache и Expires: Thu, 01 Jan 1970 00:00:01 GMT
expires off;nginx не трогает эти заголовки — так по умолчанию

max-age — сколько секунд браузер может брать файл из своей копии, не спрашивая сервер. no-cache — копию хранить можно, но перед каждым показом браузер проверяет у сервера, не изменился ли файл.

Время пишут числом с буквой: s — секунды, m — минуты, h — часы, d — дни, w — недели, M — месяцы по 30 дней, y — годы по 365 дней. Регистр важен: m — минуты, M — месяцы.

Если приложение за proxy_pass само прислало Cache-Control, expires заменит его своим значением.

Какие ответы получают срок

nginx добавляет Expires и Cache-Control только к ответам с кодами 200, 201, 204, 206, 301, 302, 303, 304, 307 и 308. К страницам ошибок — 404, 403, 500 — срок не добавится.

Где писать expires

expires можно писать в блоках http, server, location и в if внутри location. Строка из блока server действует во всех его блоках location, где нет своей строки expires.

Поэтому в server её лучше не ставить: долгий срок получат и страницы HTML, и посетители не увидят изменений на сайте, пока срок не кончится. Пишите expires в отдельном location для файлов, как в примере выше.

Что делать после обновления файлов

Пока срок не кончился, браузер берёт файл из своей копии: посетитель может видеть старые стили. Поэтому при изменении файла меняют его адрес в ссылке на странице: добавляют номер версии — style.css?v=2 вместо style.css?v=1 — или переименовывают файл.

Для браузера это новый адрес, и он скачает файл заново. nginx отдаст тот же файл: часть адреса после знака ? при поиске файла не учитывается.

Как проверить

Вместо адреса — адрес картинки или файла стилей с вашего сайта:

curl -sI 'https://example.com/css/style.css' | grep -i 'cache-control\|expires'

Для expires 30d в ответе будут строки Cache-Control: max-age=2592000 и Expires с датой. curl может показать имена заголовков маленькими буквами — это то же самое. Если строк нет, запрос не попал в блок с expires: проверьте расширение файла в списке и что после правки был reload.

Что ещё умеет curl — команды wget и curl.

Ошибки и как их исправить

Что видитеЧто делать
после правки картинки или стили отвечают 404их отдаёт приложение, а не nginx с диска — что делать
посетители видят старые стилипоменяйте адрес файла — как
"expires" directive invalid valueошибка в значении: число и буква пишутся вместе, без пробела, например 30d
"expires" directive is duplicateв одном блоке две строки expires: оставьте одну
страницы сайта не обновляются у посетителейexpires стоит в блоке server или location /: перенесите его в блок для файлов

Источники

Сверено 14 октября 2026 года.

Что почитать дальше