Настройка nginx для статики
Конфигурируем nginx для статического сайта или блога
Настройка vhost и отдача статики
Один nginx может обслуживать несколько виртуальных хостов (vhost), различая их по заголовку
Host
в запросе. При запросе из браузера доменное имя, такое какexample.com
, автоматически попадает в заголовокHost
.
Пример:
server {
listen 8080;
listen [::]:8080;
server_name example.com example.local localhost;
root /app/public;
location / {
index index.html;
}
}
Пояснения к примеру:
- nginx будет прослушивать порт 8080 для протоколов IPv4 и IPv6
- HTTPS не включён, то есть используется HTTP без TLS/SSL
- виртуальный сервер настроен на три доменных имени:
example.com
,example.local
,localhost
- статика будет отдаваться для всех URL Path сайта из каталога
/app/public
- если файл, соответствующий URL Path, не найден в
/app/public
, то будет возвращена страница 404
Кеширование статики
Пример:
server {
# Другие директивы
location ~* \.(svg|png|webp|jpg|jpeg|gif|ico) {
expires 30d;
}
location ~* \.(css|js|woff|woff2|webmanifest) {
expires 180d;
}
}
Пояснения к примеру:
- Директива
expires 30d;
установит заголовки, чтобы браузер хранил статику 30 дней, напримерCache-Control: max-age=2592000
Expires: Sun, 11 Mar 2025 13:26:14 GMT
(+30 дней от 9 февраля 2025)
- Кеширование включено для типовой статики:
- изображений в форматах SVG/PNG/WEBP/JPEG/GIF/ICO — на 30 дней
- стилей CSS, скриптов JS, шрифтов в форматах WOFF/WOFF2, файла Web App Manifest — на 180 дней
- Хранить можно и дольше — но не забывайте:
- сайт меняется и его статика тоже
- кеш клиента не безграничен и может очищаться от старых файлов
Версионирование статики
Если кеширование есть, а версионирования статики нет, то при обновлении сайта у клиента могут «поехать» стили и сломаться JavaScript.
Версионирование статики можно вести:
- Автоматически — средствами генератора статического сайта
- Вручную — силами разработчика сайта
Популярные методы версионирования:
- Каждый релиз сайта (движка сайта, стилей, скриптов) сопровождать номером версии и указывать номер версии в HTML
- В префиксе URL Path:
/css/v89/main.css
- В названии файла:
/css/main_v89.css
- В Query параметре:
/css/main.css?v=89
- В префиксе URL Path:
- Использовать хеш содержимого файла и указывать его в HTML
- В префиксе URL Path:
/css/d220a4f/main.css
- В названии файла:
/css/main_d220a4f.css
- В Query параметре:
/css/main.css?v=d220a4f
- В префиксе URL Path:
Сжатие gzip
Сжатие в gzip особенно полезно для мобильных устройств, которые часто работают с пониженной скоростью и повышенными задержами сети.
Пример:
server {
# ... другие директивы
gzip on;
gzip_types text/html text/css application/javascript image/svg+xml text/xml application/xml+rss;
gzip_proxied no-cache no-store private expired auth;
gzip_comp_level 6;
}
Пояснения к примеру:
- В примере включено GZIP сжатие «на лету» для HTML, CSS, JS, SVG файлов, а также для XML (например, sitemap) и XML+RSS (для RSS ленты)
- Директива
gzip_proxied
включает сжатие для клиентов, использующих proxy сервер- proxy часто включены в офисных компьютерах различных организаций
- Уровень сжатия установлен на 6
- допустимый диапазон директивы
gzip_comp_level
— от 1 до 9 - по умолчанию
gzip_comp_level=1
- обзор уровней сжатия есть в статье GZip и nginx: влияние на производительность
- допустимый диапазон директивы
Если всё настроено верно, то в браузере в DevTools вы сможете увидеть заголовок ответа Content-Encoding: gzip
.
Для каких MIME типов включать GZIP?
Стоит сжимать все текстовые форматы: HTML, CSS, JS, SVG. Минифицированные файлы CSS/JS тоже стоит сжимать.
Нет смысла включать GZIP сжатие:
- Для изображений PNG, JPEG, WEBP, GIF, потому что сжатие заложено в алгоритмы кодирования изображений
- тем не менее, можно сжать сами изображения лучше — подробности ищите по запросам «png optimizer», «jpeg optimizer»
- Для web шрифтов в формате WOFF и WOFF2 — в них заложено сжатие алгоритмами deflate и brotli соответственно
- Для видео и аудио в типовых форматах: OGG, MP3, MP4 и так далее — сжатие заложено в алгоритмы кодирования видео/аудио
Посмотреть доступные для nginx MIME типы в Linux можно командой:
cat /etc/nginx/mime.types
Использование gzip_static
Иногда при создании сайта есть возможность заранее сжимать файлы в GZIP.
Допустим, генератор статического сайта сжимает файлы HTML/JS/CSS в GZIP архивы:
index.html
сжимается вindex.html.gz
js/article-toc.js
сжимается вjs/article-toc.js.gz
Тогда в nginx можно задействовать директиву gzip_static с тремя вариантами:
off
(по умолчанию) — выключает поиск предварительно сжатого файлаon
— включает поиск предварительно сжатого файлаalways
— всегда использует только предварительно сжатые файлы без проверки
Пример:
server {
# ... другие директивы
# Отдавать сжатый контент из файла *.gz, если он найден
gzip_static on;
С такой конфигурацией nginx будет:
- отдавать контент из файла
*.gz
, если есть файл, соответствующий URL - действовать обычным путём с учётом других директив
gzip*
, если файла*.gz
нет