AdTech AI PostgreSQL О компании
Web · nginx 14 февраля, 2025 Сергей Томулевич

Ресайз изображений на лету

Динамическая обработка изображений через nginx-модули image_filter, proxy_module и secure_link. Resize, crop без вызова бэкенда с защитой от DDoS.

Задача

Решение для динамического изменения размера изображений в веб-приложениях с соблюдением трёх основных требований:

Конфигурация установки nginx

Требуются три модуля:

При компиляции nginx указываются флаги: --with-http_secure_link_module --with-http_image_filter_module.

Конфигурация nginx

Основной location на главном хосте с кешированием:

proxy_cache_path /www/myprojects/cache levels=1:2 keys_zone=image-preview:10m;

location ~ ^/preview/([cir])/(.+) {
    set $oper $1;
    set $remn $2;
    proxy_pass http://myproject.ru:81/$oper/$remn;
    proxy_intercept_errors on;
    error_page 404 = /preview/404;
    proxy_cache image-preview;
    proxy_cache_key "$host$document_uri";
    proxy_cache_valid 200 1d;
    proxy_cache_valid any 1m;
}

location = /preview/404 {
    internal;
    default_type image/gif;
    alias /www/myprojects/image/noimage.gif;
}

Отдельный хост на порту 81:

server {
    server_name myproject.ru;
    listen 81;
    secure_link_secret secret;
    error_page 403 404 415 500 502 503 504 = @404;

    location ~ ^/i/[^/]+/(.+) {
        alias /www/myproject.ru/images/$1;
        try_files "" @404;
        if ($secure_link = "") { return 404; }
        image_filter size;
    }

    location ~ ^/c/[^/]+/(\d+|-)x(\d+|-)/(.+) {
        set $width $1;
        set $height $2;
        alias /www/myproject.ru/images/$3;
        try_files "" @404;
        if ($secure_link = "") { return 404; }
        image_filter crop $width $height;
    }

    location ~ ^/r/[^/]+/(\d+|-)x(\d+|-)/(.+) {
        set $width $1;
        set $height $2;
        alias /www/myproject.ru/images/$3;
        try_files "" @404;
        if ($secure_link = "") { return 404; }
        image_filter resize $width $height;
    }

    location @404 { return 404; }
}

URL-структура

Использование в приложении (Perl)

sub proxy_image {
    use Digest::MD5 qw /md5_hex/;
    my %params = @_;
    my $filter = {
        size => 'i',
        resize => 'r',
        crop => 'c'
    }->{$params{filter}} || 'r';
    my $path = ($filter ne 'i' ?
        ($params{height} || '_') . 'x' . ($params{width} || '_') . '/' :
        ()
    ) . $params{source};
    my $md5 = md5_hex($path . 'secret');
    $path = '/preview/' . $filter . '/' . $md5 . '/' . $path;
    return $path;
}

Грабли

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

Готовы посчитать собственный стек? Расскажем, какие модули и какая нагрузка нужны под вашу задачу.

to@prototypes.ventures