Кэширование статических файлов с помощью nginx

Кэширование статических файлов (изображений, CSS, JS) в Nginx значительно ускоряет загрузку сайта и снижает нагрузку на сервер. Существует два основных подхода: кэширование в браузере клиента и кэширование на стороне сервера Nginx (прокси-кэш). В таблице ниже показаны их ключевые отличия:

ХарактеристикаКэш в браузере (директива expires)Прокси-кэш Nginx (директива proxy_cache)
Где хранитсяЛокально в браузере пользователяНа диске или в памяти сервера Nginx
Основная цельПовторное использование локальных ресурсов при повторных посещенияхЗащита и разгрузка бэкенда, ускорение доступа к медленным источникам
Ключевые директивыexpires, add_header Cache-Controlproxy_cache_path, proxy_cache, proxy_cache_valid
Лучший сценарийВсегда, для стандартных статических файлов сайтаЕсли файлы лежат на медленном сетевом диске или нужно снизить нагрузку на основное приложение
СложностьПростая, базовая настройкаСредняя, требует больше конфигурации

🛠️ Практическая настройка

1. Настройка кэширования в браузере (основной и рекомендуемый метод)

Это базовая и самая важная настройка. Найдите блок server в конфигурации вашего сайта (обычно в /etc/nginx/nginx.conf или /etc/nginx/sites-available/) и добавьте правило location для статических файлов.

Базовый пример: Установите кэш для распространённых типов файлов.

location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg)$ {
    # Корневая директория файлов. Измените на актуальный путь для вашего сайта.
    root /var/www/your_site;
    # Установить срок хранения кэша в браузере на 30 дней
    expires 30d;
    # Опционально: явно добавить заголовок Cache-Control
    add_header Cache-Control "public, no-transform";
}

Расширенный пример: Разное время кэширования для разных типов файлов.

# Изображения, шрифты, медиа — кэшируем надолго (30 дней)
location ~* \.(jpg|jpeg|png|gif|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|woff|woff2)$ {
    expires 30d;
    access_log off; # Опционально: отключить логирование для снижения нагрузки на диск
    add_header Cache-Control "public";
}

# CSS и JS — кэшируем очень надолго (1 год), если в имени файла есть хэш версии
location ~* \.(css|js)$ {
    expires 1y;
    access_log off;
    add_header Cache-Control "public";
}

# Для часто меняющихся HTML и JSON — отключаем или сильно ограничиваем кэш
location ~* \.(html|json)$ {
    expires -1; # "Просрочен сразу", означает "не кэшировать"
    add_header Cache-Control "no-store, no-cache, must-revalidate";
}

2. Настройка прокси-кэширования в Nginx

Этот метод полезен, если ваши статические файлы физически расположены на медленном удалённом хранилище (например, сетевой диск или другой сервер), или когда Nginx выступает в роли защитного прокси для бэкенд-приложения.

Это более сложная настройка: сначала нужно определить зону кэша в блоке http, а затем активировать её в нужном location.

# В блоке http определяем путь и параметры кэша
http {
    # ... другие настройки ...

    # Определяем зону кэша с именем static_cache
    # /data/nginx/cache:  каталог на диске для хранения файлов кэша
    # keys_zone=static_cache:10m: выделяем 10 МБ оперативной памяти под ключи кэша
    # max_size=1g: максимальный размер кэша на диске — 1 ГБ
    # inactive=60m: файлы кэша, к которым не обращались 60 минут, будут удалены
    proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=static_cache:10m max_size=1g inactive=60m use_temp_path=off;

    server {
        listen 80;
        server_name your_domain.com;

        location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
            # Адрес исходного сервера, где лежат файлы (в примере — локальный)
            proxy_pass http://127.0.0.1:8080;

            # Включаем кэширование, используя определённую выше зону
            proxy_cache static_cache;
            # Ключ кэша (по умолчанию обычно достаточно)
            proxy_cache_key $scheme$proxy_host$request_uri;
            # Кэшировать ответы 200 и 302 на 1 час
            proxy_cache_valid 200 302 1h;
            # Кэшировать ответы 404 на 1 минуту
            proxy_cache_valid 404 1m;

            # Опционально: добавить заголовок для отладки, указывающий статус попадания в кэш
            add_header X-Cache-Status $upstream_cache_status;

            # Также можно установить срок действия кэша для браузера
            expires 7d;
            add_header Cache-Control "public";
        }
    }
}

✅ Проверка и применение

  1. Внесите изменения: Добавьте подходящий фрагмент конфигурации в файл настроек вашего сайта в Nginx.
  2. Проверьте синтаксис: После сохранения выполните команду sudo nginx -t. Она проверит корректность синтаксиса конфигурации.
  3. Примените изменения: Если проверка прошла успешно, выполните sudo nginx -s reload, чтобы перезагрузить конфигурацию без остановки сервера.
  4. Убедитесь, что всё работает:
    • Для кэша браузера: Откройте инструменты разработчика в браузере (F12), перейдите на вкладку Сеть (Network) и загрузите статический файл (например, изображение). В ответных заголовках (Response Headers) вы должны увидеть Cache-Control и Expires с заданными вами значениями.
    • Для прокси-кэша: Помимо проверки заголовков кэша браузера, следите за добавленным заголовком X-Cache-Status. При первом запросе его значение будет MISS, а при повторном — HIT. Это означает, что Nginx отдал файл из своего кэша.

🔧 Дополнительные советы по оптимизации

  • Используйте сжатие Gzip: Включите сжатие (gzip on;) и настройте gzip_types для текстовых файлов (CSS, JS, HTML). Это уменьшит объём передаваемых данных.
  • Контроль версий файлов: Для файлов CSS и JavaScript используйте "отпечатки версий" (version hash) в именах файлов (например, style.a1b2c3.css). Это позволяет безопасно устанавливать очень долгий срок кэширования (вплоть до года) в браузере, так как при любом изменении содержимого имя файла изменится, и браузер загрузит новую версию.
  • Очистка кэша: Если вы используете прокси-кэш и обновили исходные файлы, вам может понадобиться очистить кэш Nginx. Для этого можно настроить механизм очистки (с помощью модуля ngx_cache_purge), либо просто удалить файлы из директории кэша (например, /data/nginx/cache) и перезагрузить Nginx.

Эти настройки должны заметно ускорить загрузку статических ресурсов вашего сайта. Рекомендую начать с настройки кэширования в браузере, так как это проще и подходит для большинства случаев. К прокси-кэшированию стоит прибегать, если доступ к исходным файлам действительно медленный.