惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
V
Vulnerabilities – Threatpost
Last Week in AI
Last Week in AI
I
InfoQ
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Help Net Security
D
Docker
www.infosecurity-magazine.com
www.infosecurity-magazine.com
B
Blog RSS Feed
Forbes - Security
Forbes - Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Latest news
Latest news
S
SegmentFault 最新的问题
J
Java Code Geeks
C
CXSECURITY Database RSS Feed - CXSecurity.com
MongoDB | Blog
MongoDB | Blog
量子位
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
F
Full Disclosure
Engineering at Meta
Engineering at Meta
AWS News Blog
AWS News Blog
月光博客
月光博客
Cisco Talos Blog
Cisco Talos Blog
V
Visual Studio Blog
雷峰网
雷峰网
博客园_首页
Project Zero
Project Zero
美团技术团队
Google DeepMind News
Google DeepMind News
IT之家
IT之家
P
Palo Alto Networks Blog
有赞技术团队
有赞技术团队
S
Security @ Cisco Blogs
U
Unit 42
C
Cisco Blogs
Hugging Face - Blog
Hugging Face - Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Security Archives - TechRepublic
Security Archives - TechRepublic
GbyAI
GbyAI
Stack Overflow Blog
Stack Overflow Blog
S
Schneier on Security
TaoSecurity Blog
TaoSecurity Blog
The Register - Security
The Register - Security
WordPress大学
WordPress大学
T
Threat Research - Cisco Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
The Last Watchdog
The Last Watchdog
Cloudbric
Cloudbric
Help Net Security
Help Net Security

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Работа с картинками в Angie
Nickmob · 2026-04-27 · via Все публикации подряд на Хабре

Уровень сложностиСредний

Время на прочтение12 мин

Охват и читатели533

Туториал

Изображения играют важную роль в любом веб‑приложении. Это могут быть элементы оформления интерфейса или основной контент сайта. В любом случае, перед разработчиками и администраторами стоит задача эффективной работы с картинками и в этой статье мы рассмотрим решения, которые реализуются веб‑сервером Angie.

Навигация по циклу

  1. Почему стоит переходить на Angie.

  2. Установка Angie из пакетов и в докере.

  3. Переезд с Nginx на Angie. Пошаговая инструкция.

  4. Настройка location в Angie. Разделение динамических и статических запросов.

  5. Перенаправления в Angie: return, rewrite и примеры их применения.

  6. Сжатие текста в Angie: статика, динамика, производительность.

  7. Серверное кэширование в Angie: тонкости настройки.

  8. Настройка TLS в Angie: безопасность и скорость.

  9. Настройка Angie в роли обратного HTTP-прокси.

  10. Балансировка нагрузки для HTTP(S) в Angie.

  11. Мониторинг Angie с помощью Console Light и API.

  12. Балансировка и проксирование L4-трафика в Angie.

  13. Клиентское кэширование в Angie.

  14. Динамические группы проксируемых серверов в Angie.

  15. Мониторинг Angie с Prometheus и Grafana.

  16. Отказоустойчивый кластер Angie с VRRP и Keepalived.

  17. Контроль доступа в Angie.

  18. Аутентификация клиентов в Angie с помощью TLS-сертификатов.

  19. Кастомизация Angie (njs, Lua, Perl).

  20. Запуск CGI-скриптов в Angie.

  21. Защита от DoS-атак в Angie стандартными модулями.

  22. Защита от DoS-атак в Angie (дополнительные средства).

  23. Автоматические TLS-сертификаты в Angie с модулем ACME.

  24. HTTP/2 и HTTP/3: настройка, достоинства и недостатки.

  25. Работа с картинками в Angie.

Видеоверсия

Для вашего удобства подготовлена видеоверсия этой статьи, доступна на Rutube, VKVideo и YouTube.

Адаптивная доставка изображений

Современные веб‑браузеры поддерживают множество форматов, решающих различные задачи. Также можно ввести классификацию этих форматов по признаку поддержки клиентами:

  • классические (полная поддержка) — JPEG, PNG, GIF;

  • новые (ограниченная поддержка) — WebP, AVIF.

Новые форматы сжатия изображений появились как побочный продукт видеокодеков VP8 (WebP) и AV1 (AVIF), при этом сохранив высокие коэффициенты сжатия. При использовании новых форматов изображений на сайте приходится сохранять совместимость со старыми клиентами, то есть использовать адаптивную доставку изображений. Для тех, которые поддерживают новый формат отдавать WebP или AVIF, а для остальных использовать классические форматы.

Реализовать адаптивную доставку можно с помощью HTML‑вёрстки, где браузер будет выбирать поддерживаемый формат самостоятельно. Такой способ потребует изменения кода страниц и поддержки со стороны веб‑приложения.

Другой способ — использовать веб‑сервер и HTTP‑заголовок Accept, в котором указываются поддерживаемые форматы. В этом варианте код страниц не меняется, при этом клиенты будут получать различные форматы в зависимости от заявленной поддержки в заголовке Accept. При этом на диске уже должны находиться версии картинок в новых форматах, отличаться они будут дополнением в имени. Например, рядом с 1.jpg мы положим 1.jpg.avif. Именно этот способ мы реализуем в этой части статьи.

Первая часть решения: определить поддержку форматов через заголовок Accept. Для этого используем определение переменных через директиву map:

http {
    map $http_accept $webp_suffix {
        "~*webp"  ".webp";
    }

    map $http_accept $avif_suffix {
        "~*avif"  ".avif";
        "~*webp"  ".webp";
    }
}

В этой части конфигурации мы создаём переменные $webp_suffix и $avif_suffix. Их значения соответствуют дополнительным расширениям файлов, которые мы будем размещать рядом с оригинальными картинками. 

Вторая часть конфигурации: настройка локации для адаптивной доставки картинок. Здесь рекомендуется выделить отдельный блок именно для нужных форматов изображений. Например, это можно сделать с помощью регулярного выражения:

location ~* \.(jpe?g|gif|png)$ {
  try_files $uri$avif_suffix $uri$webp_suffix $uri =404;
  add_header Cache-Control "max-age=31536000, public, no-transform, immutable";
}

В примере выше мы выделяем локацию для обслуживания файлов с расширениями jpg, jpeg, gif и png. Основную часть работы выполняет директива try_files, которая использует переменные $webp_suffix и $avif_suffix для дополнения имени файла (.webp,.avif). В случае нахождения файла на диске отдаётся новая версия, иначе — обычный вариант. Вторая директива (add_header) отвечает за клиентское кэширование ресурса, подробнее этот вопрос разобран в отдельной статье. Продемонстрируем работу этого блока псевдокодом.

$ ls
1.jpg 1.jpg.avif 1.jpg.webp

# Client
>GET /1.jpg
>Accept: webp,avif,*/*

# Angie
< $webp_suffix = ‘.webp’;
< $avif_suffix = ‘.avif’;
< try_files 1.jpg.avif 1.jpg.webp 1.jpg =404;
< send 1.jpg.avif

Клиент получит содержимое файла 1.jpg.avif с корректным заголовком Content‑Type (если он заранее был прописан в файле /etc/angie/mime.types). С точки зрения HTML‑вёрстки никаких изменений не требуется (тэг картинки может выглядеть как <img src="1.jpg">).

Стоит заметить, что такая схема хорошо подходит для прямой работы с клиентами. Если между Angie и клиентом работает кэширующий слой (например, CDN), то стоит проверить корректность работы схемы и возможно стоит добавить заголовок Vary: Accept, который проинструктирует кэширующий сервер о зависимости ответа от заголовка запроса Accept.

Пока мы занимались только доставкой готовых картинок, но веб‑сервер Angie способен обрабатывать изображения самостоятельно. Начнём с возможностей масштабирования изображений.

Масштабирование, обрезка и поворот картинок

Работа с изображениями в Angie реализована в модуле Image Filter. Модуль собран динамически и поставляется в отдельном пакете. Установка:

apt install angie-module-image-filter

Подключение модуля (в контексте main):

load_module modules/ngx_http_image_filter_module.so;

Модуль опирается на библиотеку libgd, то есть поддержка форматов ограничена возможностями установленной в системе библиотеки (при использовании установки из пакетов). Например, в Ubuntu 24.04 библиотека поддерживает WebP, но не поддерживает AVIF. Модуль Image Filter также имеет поддержку формата HEIC, но его крайне слабая поддержка браузерами (только Apple‑системы) делает его бесполезным для веб‑разработки.

Первое, что позволяет модуль, это масштабирование картинок на лету. Такой подход позволяет не нарезать все требуемые версии картинок заранее, а использовать одну версию изображения на диске. Конечно, преобразование картинок — затратная операция для процессора, поэтому позже мы будем обсуждать возможности кэширования результатов.

Для динамического масштабирования картинок достаточно создать локацию для картинок с директивой image_filter и сопутствующими параметрами. 

server {
   listen 80;
   root /var/www/image;

  location ~* ^/img/(?<width>\d+|-)x(?<height>\d+|-)/(?<file>.+\.jpe?g)$ {
    alias /var/www/image/img/$file;	
    image_filter resize $width $height;
	image_filter_jpeg_quality 80;
	image_filter_interlace on;
	image_filter_sharpen 20;
	error_page 415 = /empty;
  }

  location = /empty {
    empty_gif;
  }
}

В этом примере мы используем локацию с регулярным выражением и сохранением частей URI в переменные ($width, $height и $file). Данный блок обслуживает только файлы типа JPEG, производит масштабирование по параметрам ширины ($width) и высоты ($height), уровень качества при компрессии установлен в 80 (image_filter_jpeg_quality). Также указана настройка создавать прогрессивную версию файла (image_filter_interlace) и добавить увеличение резкости (image_filter_sharpen). Для того, чтобы сервер нашел картинку на диске, используется директива alias с путём к исходному файлу. Для обработки ошибки 415 (Unsupported Media Type) создана локация, возвращающая пустой однопиксельный GIF. 

Тестовые картинки должны быть расположены в директории /var/www/image/img/. Чтобы получить масштабированную версию можно отправлять запросы вида:

GET /img/210x210/1.jpg
GET /img/210x-/1.jpg
GET /img/-x210/1.jpg

Первый запрос определяет одновременно и ширину и высоту картинки. В этом случае будет использоваться пропорциональное масштабирование (как и всегда) и картинка будет «вписана» в указанный прямоугольник. Во втором запросе указана только ширина, а в третьем только высота.

Максимальный размер картинок, с которыми может работать модуль, определяется директивой image_filter_buffer и по умолчанию равен 1 MБ.

Аналогичная конфигурация для lossless‑форматов (PNG, GIF):

location ~ ^/img/(?<width>\d+)x(?<height>\d+|-)/(?<file>.+\.(png|gif))$ {
  alias /var/www/image/img/$file;
  image_filter resize $width $height;
  image_filter_interlace on;
  image_filter_sharpen 20;
  error_page 415 = /empty;
}

Стоит заметить, что такая конфигурация даёт максимальную гибкость в выборе размеров картинок, но может стать целью DoS‑атаки на сервер, когда злоумышленник будет запрашивать большое количество картинок с произвольными размерами. В качестве защиты рекомендуется создать локации с фиксированными параметрами размеров и использовать кэширование.

Кроме масштабирования, модуль позволяет обрезать (crop) изображения. Конфигурация аналогична первой:

location ~ ^/img/(?<width>\d+|-)x(?<height>\d+|-)/(?<file>.+\.jpe?g)$ {
  alias /var/www/image/img/$file;
  image_filter crop $width $height;
  image_filter_jpeg_quality 80;
  image_filter_interlace on;
  image_filter_sharpen 20;
  error_page 415 = /empty;
}

Преобразование crop будет масштабировать картинку по большей стороне и далее обрезать лишние края, используя второй параметр размера. Например, для портретной ориентации картинки (1000×1500 px) при запросе размеров 400×400 сначала применится масштабирование до 400 по ширине, а затем обрезка по высоте до 400 пикселей (останется центральная часть изображения).

Также модуль умеет вращать картинки на углы, кратные 90. Для этого можно использовать параметр rotate директивы image_filter. При этом поворот можно использовать совместно с масштабированием или обрезкой:

location ~ ^/img/(?<width>\d+|-)x(?<height>\d+|-)/(?<file>.+\.jpe?g)$ {
  alias /var/www/image/img/$file;
  image_filter resize $width $height;
  image_filter rotate 90;
  image_filter_jpeg_quality 80;
  image_filter_interlace on;
  image_filter_sharpen 20;
  error_page 415 = /empty;
}

В примере выше поворот на 90 градусов против часовой стрелки происходит после изменения размеров, в то время как при обрезке (crop) поворот происходит до изменения размеров.

Также модуль умеет проверять формат изображения (действие test) и возвращать данные о размере картинки (действие size). 

Итак, мы научились изменять размеры, обрезать и поворачивать изображения, пора поговорить о вопросах оптимизации.

Конвертация и оптимизация

В начале статьи мы упоминали, что модуль Image Filter в Angie поддерживает различные форматы (при соответствующей поддержке libgd): JPEG, WebP, AVIF, HEIC. В отличие от модуля в Nginx, в Angie добавлена возможность конвертирования изображений между форматами. Это даёт интересные возможности по созданию системы оптимизации изображений средствами веб‑сервера.

Первый сценарий: конвертировать изображения из старых форматов в новые. Конечно, здесь нам пригодятся приёмы из адаптивной доставки изображений в первой части статьи. То есть сначала мы должны определить, поддерживает ли клиент нужный формат и в случае поддержки дать ему оптимизированную версию.

Определим префиксы для новых форматов на основе заголовка запроса Accept:

http {
   map $http_accept $webp_prefix {
        "~*webp"  "-webp";
    }

    map $http_accept $avif_prefix {
        "~*avif"  "-avif";
        "~*webp"  "-webp";
    }
}

Теперь немного изменим структуру серверов в Angie. Первый будет отвечать за фронтенд, а второй заниматься обработкой картинок. Конфигурация фронта:

server {
    listen 443 ssl;
    root /var/www/image;
    rewrite ^/img(?<file>/.+)$ /img${webp_prefix}$file last;

    location ~ ^/img.+/.+\.(jpe?g|png|gif)$ {
       add_header Vary Accept;
       expires max;
       error_page 404 = @resize;
    }

    location @resize {
       add_header Vary Accept;
       expires max;
       proxy_pass         http://127.0.0.1:8081$uri;
    }
}

Это сервер, который будет отдавать изображения напрямую, если они есть на диске, либо проксировать на другой сервер (http://127.0.0.1:8081) для конвертации. Обратите внимание на директиву rewrite: она позволит перенаправить запрос внутри сервера на WebP‑версию при поддержке браузером. 

Теперь конфигурация сервера для обработки картинок:

server {
    listen 8081;
    root /var/www/image;

    location ~ ^/img-webp/(?<file>.+)$ {
        alias /var/www/image/img/$file;
        image_filter convert webp;
        image_filter_webp_quality 80;
        error_page 415 = /empty;
    }
}

Теперь при запросе картинки JPEG мы получаем конвертированное в формат WebP изображение:

curl --head -H "Accept: image/webp" https://localhost/img/1.jpg

HTTP/2 200 
server: Angie/1.11.4
...
content-type: image/webp
vary: Accept

Аналогичная конфигурация по конвертации изображений для формата AVIF:

location ~ ^/img-avif/(?<width>\d+)x(?<height>\d+|-)/(?<file>.+)$ {
    alias /var/www/image/img/$file;
    image_filter convert avif;
    image_filter resize $width $height;
    image_filter_avif_quality 80 6;
    error_page 415 = /empty;
}

Можно заметить, что при изменении формата используется режим convert директивы image_filter. Качество сжатия задаётся с помощью директив image_filter_avif_quality и image_filter_webp_quality

Процесс конвертации можно совмещать с изменением размеров, например для WebP:

location ~ ^/img-webp/(?<width>\d+)x(?<height>\d+|-)/(?<file>.+)$ {
  alias /var/www/image/img/$file;
  image_filter convert webp;
  image_filter resize $width $height;
  image_filter_webp_quality 80;
  image_filter_sharpen 20;
  error_page 415 = /empty;
}

Процесс обработки и конвертации изображений создаёт значительную нагрузку на процессор сервера, поэтому следующий логичный шаг в нашей системе — кэширование результатов для снижения нагрузки на сервер.

Кэширование результатов

Сохранять результаты обработки картинок модулем Image Filter можно двумя способами: классическое серверное кэширование proxy_cache и сохранение результатов на диск с помощью proxy_store. Начнём со второго метода.

Для использования proxy_store необходимо модифицировать конфигурацию фронтенд‑части нашего сервера, а именно локацию с проксированием:

location @resize {
  add_header Vary Accept;
  expires max;
  proxy_pass     http://127.0.0.1:8081$uri;
  proxy_store	/var/www/image$uri;
}

Теперь при запросе картинки для конвертации в WebP:

curl --head -H "Accept: image/webp" https://localhost/img/1.jpg

Результат конвертации будет сохранён в виде файла по адресу /var/www/image/img‑webp/1.jpg. Если запросить изменение размеров:

curl --head -H "Accept: image/webp" https://localhost/img/100x100/1.jpg

То результирующий файл будет сохранён по следующему пути: /var/www/image/img-webp/100x100/1.jpg. Повторные запросы к этим версиям картинок будут обработаны как статические, без дополнительных затрат процессора.

Таким образом, мы решили проблему повторной генерации версий и снизили нагрузку. Но что будет, если сохранённые версии будут больше не нужны? С таким подходом — только ручная чистка и самостоятельное обслуживание хранилища картинок. 

Второй подход позволяет гибко настраивать параметры кэширования версий и избавляет от необходимости ручного управления. Здесь мы будем использовать серверное кэширование. Для начала определим общие параметры кэширования (зону, ключ и время жизни):

http {
    proxy_cache_path	/var/local/angie/cache  levels=1:2 inactive=30d keys_zone=one:10m:file=/etc/angie/cache.state max_size=1G;
}

Итак, мы создали зону кэширования под названием one, определили размер разделяемой памяти (10m) и максимальный размер на диске (max_size=1G). Для ускорения загрузки статуса кэша добавлен файл с сохранением состояния (file). 

Теперь внесём изменения в конфигурацию проксирующего location:

location @resize {
  add_header Vary Accept;
  expires max;
  proxy_pass     http://127.0.0.1:8081$uri;
  proxy_cache                 one;
  proxy_cache_key             "$host$uri";
  proxy_cache_lock 			on;
  proxy_cache_min_uses 		2;
  proxy_ignore_headers 		"Cache-Control" "Expires";
  proxy_cache_use_stale 	updating error timeout invalid_header http_500 http_502 http_504;
  proxy_cache_background_update on;
  proxy_cache_valid           200 14d;
  proxy_cache_valid           any 1m;
}

В новой версии конфигурации мы включили использование кэша в зоне one, определили ключ кэширования. Результат будет кэшироваться после двух запросов, чтобы не засорять диск редкими вариантами картинок (proxy_cache_min_uses). Также мы разрешили использовать старые версии картинок при обновлении кэша или в случае проблем у сервера. Время актуальности кэша ограничено 14 днями. Также будут кэшироваться ответы с ошибками. Эта конфигурация всего лишь показывает пример реализации задачи, конкретные значения нужно подбирать исходя из требований приложения.

Теперь у нас на вооружении два метода сохранения результатов преобразования картинок, используйте тот, который вам больше подходит.

Итоги

Подведём итоги по работе с картинками. Веб‑сервер Angie обладает широкими возможностями для работы с изображениями. Первый метод адаптивной доставки задействует лишь механизм переменных и директиву try_files, оставляя всю работу с изображениям за кадром. Модуль Image Filter напротив, берёт работу по изменению размеров и конвертации форматов на себя, избавляя от необходимости предварительной обработки картинок. Выбор подхода к работе с изображениями остаётся за читателем: либо подробная оптимизация и минимальная нагрузка на сервер с предварительно обработанными картинками, либо динамическая нарезка картинок без усложнения веб‑приложения.