Nginx рдЖрдгрд┐ LuaJIT (OpenResty) рд╡рд╛рдкрд░реВрди рдлреНрд▓рд╛рдпрд╡рд░ рдкреНрд░рддрд┐рдорд╛рдВрдЪрд╛ рдЖрдХрд╛рд░ рдмрджрд▓рд╛

рдЖрддрд╛ рдмрд░рд╛рдЪ рдХрд╛рд│, рд▓реЗрдЦрд╛рдиреЗ рдкреНрд░реЗрд░рд┐рдд рдлреНрд▓рд╛рдп рд╡рд░ рдкреНрд░рддрд┐рдорд╛ рдЖрдХрд╛рд░ рдмрджрд▓рдгреЗ рдкреНрд░рддрд┐рдореЗрдЪрд╛ рдЖрдХрд╛рд░ рдмрджрд▓рдгреЗ рд╡рд╛рдкрд░реВрди рдХреЙрдиреНрдлрд┐рдЧрд░ рдХреЗрд▓реЗ рд╣реЛрддреЗ ngx_http_image_filter_module рдЖрдгрд┐ рд╕рд░реНрд╡рдХрд╛рд╣реА рдЬрд╕реЗ рдкрд╛рд╣рд┐рдЬреЗ рддрд╕реЗ рдХрд╛рд░реНрдп рдХреЗрд▓реЗ. рдкрд░рдВрддреБ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдЙрджреНрднрд╡рд▓реА рдЬреЗрд╡реНрд╣рд╛ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХрд╛рд▓рд╛ рдХрд╛рд╣реА рд╕реЗрд╡рд╛рдВрд╡рд░ рдЕрдкрд▓реЛрдб рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЕрдЪреВрдХ рдкрд░рд┐рдорд╛рдгрд╛рдВрд╕рд╣ рдкреНрд░рддрд┐рдорд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрддреЗ, рдХрд╛рд░рдг... рдпрд╛ рддреНрдпрд╛рдВрдЪреНрдпрд╛ рддрд╛рдВрддреНрд░рд┐рдХ рдЧрд░рдЬрд╛ рд╣реЛрддреНрдпрд╛. рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЖрдордЪреНрдпрд╛рдХрдбреЗ рдЖрдХрд╛рд░рд╛рдЪреА рдореВрд│ рдкреНрд░рддрд┐рдорд╛ рдЕрд╕рд▓реНрдпрд╛рд╕ 1200 ├Ч 1200, рдЖрдгрд┐ рдЖрдХрд╛рд░ рдмрджрд▓рддрд╛рдирд╛ рдЖрдкрдг рдЕрд╕реЗ рдХрд╛рд╣реАрддрд░реА рд▓рд┐рд╣рд┐рддреЛ ?resize=600├Ч400, рдирдВрддрд░ рдЖрдореНрд╣рд╛рд▓рд╛ рд╕рд░реНрд╡рд╛рдд рд▓рд╣рд╛рди рдХрд┐рдирд╛рд░реА, рдЖрдХрд╛рд░рд╛рд╕рд╣ рдкреНрд░рдорд╛рдгрд╛рдиреБрд╕рд╛рд░ рдХрдореА рдХреЗрд▓реЗрд▓реА рдкреНрд░рддрд┐рдорд╛ рдорд┐рд│рддреЗ 400 ├Ч 400. рдЙрдЪреНрдЪ рд░рд┐рдЭреЛрд▓реНрдпреВрд╢рди (рдЕрдкрд╕реНрдХреЗрд▓) рдЕрд╕рд▓реЗрд▓реА рдкреНрд░рддрд┐рдорд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдгреЗ рджреЗрдЦреАрд▓ рдЕрд╢рдХреНрдп рдЖрд╣реЗ. рддреНрдпрд╛. ?resize=1500├Ч1500 рд╕рдорд╛рди рдкреНрд░рддрд┐рдорд╛ рдкрд░рдд рдХрд░реЗрд▓ 1200 ├Ч 1200

рд╣рд╛ рд▓реЗрдЦ рдмрдЪрд╛рд╡рд╛рд╕рд╛рдареА рдЖрд▓рд╛ рдУрдкрдирд░реЗрд╕реНрдЯреА: NGINX рд▓рд╛ рдкреВрд░реНрдг рдНрдкреНрд▓рд┐рдХреЗрд╢рди рд╕рд░реНрд╡реНрд╣рд░рдордзреНрдпреЗ рдмрджрд▓рдгреЗ Nginx рд▓реБрдЖ рдЖрдгрд┐ рд▓рд╛рдпрдмреНрд░рд░реА рд╕реНрд╡рддрдГ рд▓реБрдЖрд╕рд╛рдареА рдХрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддреЗ рд╣реЗ рд╕рдордЬреВрди рдШреЗрдгреНрдпрд╛рд╕рд╛рдареА isage/lua-imagick - рд▓реБрдЖ рд╢реБрджреНрдз-рд╕реА рдЗрдореЗрдЬрдореЕрдЬрд┐рдХрд▓рд╛ рдмрдВрдзрдирдХрд╛рд░рдХ. рд╣рд╛ рдЙрдкрд╛рдп рдХрд╛ рдирд┐рд╡рдбрд▓рд╛ рдЧреЗрд▓рд╛, рдЖрдгрд┐ рдореНрд╣рдгрд╛, рдЕрдЬрдЧрд░рд╛рдд рдХрд╛рд╣реАрддрд░реА рдирд╛рд╣реА - рдХрд╛рд░рдг рддреЗ рдЬрд▓рдж рдЖрдгрд┐ рд╕реЛрдпреАрд╕реНрдХрд░ рдЖрд╣реЗ. рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдХреЛрдгрддреНрдпрд╛рд╣реА рдлрд╛рдЗрд▓реНрд╕ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рдЪреА рджреЗрдЦреАрд▓ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╛рд╣реА, Nginx рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рдирдордзреНрдпреЗ рд╕рд░реНрд╡рдХрд╛рд╣реА рдпреЛрдЧреНрдп рдЖрд╣реЗ (рдкрд░реНрдпрд╛рдпреА).

рддрд░ рдЖрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рд╣рд╡реЗ рдЖрд╣реЗ

рдбреЗрдмрд┐рдпрдирд╡рд░ рдЖрдзрд╛рд░рд┐рдд рдЙрджрд╛рд╣рд░рдгреЗ рджрд┐рд▓реА рдЬрд╛рддреАрд▓.

nginx рдЖрдгрд┐ nginx-extras рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдд рдЖрд╣реЗ

apt-get update
apt-get install nginx-extras

LuaJIT рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдд рдЖрд╣реЗ

apt-get -y install lua5.1 luajit-5.1 libluajit-5.1-dev

рдЗрдореЗрдЬрдореЕрдЧрд┐рдХ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдд рдЖрд╣реЗ

apt-get -y install imagemagick

рдЖрдгрд┐ рд▓рд╛рдпрдмреНрд░рд░реА рдЬрд╛рджреВрдЯреЛрдгрд╛ рдорд╛рдЭреНрдпрд╛ рдмрд╛рдмрддреАрдд, рдЖрд╡реГрддреНрддреА 6 рд╕рд╛рдареА

apt-cache search libmagickwand
apt-get -y install libmagickwand-6.q16-3 libmagickwand-6.q16-dev

рдмрд┐рд▓реНрдбрд┐рдВрдЧ lua-imagick

рдЖрдореНрд╣реА рд░реЗрдкреЙрдЬрд┐рдЯрд░реА рдХреНрд▓реЛрди рдХрд░рддреЛ (рдХрд┐рдВрд╡рд╛ рдЭрд┐рдк рдШреНрдпрд╛ рдЖрдгрд┐ рдЕрдирдкреЕрдХ рдХрд░рд╛)

cd ~
git clone https://github.com/isage/lua-imagick.git
cd lua-imagick
mkdir build
cd build
cmake ..
make
make install

рдЬрд░ рд╕рд░реНрд╡ рдХрд╛рд╣реА рдареАрдХ рдЭрд╛рд▓реЗ, рддрд░ рддреБрдореНрд╣реА Nginx рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░реВ рд╢рдХрддрд╛.

рдореА рдмреЕрдХрдПрдВрдб рд╣реЛрд╕реНрдЯрдЪреНрдпрд╛ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рдирдЪреЗ рдЙрджрд╛рд╣рд░рдг рджреЗрдИрди, рдЬреЗ рдЦрд░реЗрддрд░ рдЖрдХрд╛рд░ рдмрджрд▓рдгреНрдпрд╛рд╕рд╛рдареА рдЬрдмрд╛рдмрджрд╛рд░ рдЖрд╣реЗ. рд╣реЗ рд╕рдореЛрд░рдЪреНрдпрд╛ рд╕рд░реНрд╡реНрд╣рд░рджреНрд╡рд╛рд░реЗ рдкреНрд░реЙрдХреНрд╕реА рдХреЗрд▓реЗ рдЬрд╛рддреЗ, Nginx рд╕рд╣ рджреЗрдЦреАрд▓, рдЬреЗрдереЗ рдХреЕрд╢рд┐рдВрдЧ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд▓рд╛рд╡рдзреАрд╕рд╛рдареА (рджрд┐рд╡рд╕) рдЖрдгрд┐ рдЗрддрд░ рдЧреЛрд╖реНрдЯреАрдВрд╕рд╛рдареА рд╣реЛрддреЗ.

nginx рдмреЕрдХрдПрдВрдб рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди

# Backend image server
server {
    listen       8082;
    listen [::]:8082;
    set $files_root /var/www/example.lh/frontend/web;
    root $files_root;
    access_log off;
    expires 1d;

    location /files {
        # ╨┤╨╡╤Д╨╛╨╗╤В╨╜╤Л╨╡ ╨╖╨╜╨░╤З╨╡╨╜╨╕╤П ╤А╨╡╤Б╨░╨╣╨╖╨░
        set $w 700;
        set $h 700;
        set $q 89;

        #1-89 allowed
        if ($arg_q ~ "^([1-9]|[1-8][0-9])$") {
            set $q $arg_q;
        }

        if ($arg_resize ~ "([d-]+)x([d+!^]+)") {  
            set $w $1;
            set $h $2;
            rewrite  ^(.*)$   /resize/$w/$h/$q$uri     last;
        }

        rewrite  ^(.*)$   /resize/$w/$h/$q$uri     last;
    }

    location ~* ^/resize/([d]+)/([d+!^]+)/([d]+)/files/(.+)$ {
        default_type 'text/plain';

        set $w $1;
        set $h $2;
        set $q $3;
        set $fname $4;

        # ╨Х╤Б╤В╤М ╨▓╨╛╨╖╨╝╨╛╨╢╨╜╨╛╤Б╤В╤М ╨▓╤Л╨╜╨╡╤Б╤В╨╕ ╨▓╨╡╤Б╤М Lua ╨║╨╛╨┤ ╨▓ ╨╛╤В╨┤╨╡╨╗╤М╨╜╤Л╨╣ ╤Д╨░╨╣╨╗
        # content_by_lua_file /var/www/some.lua;
        # lua_code_cache off; #dev
        content_by_lua '
        local magick = require "imagick"
        local img = magick.open(ngx.var.files_root .. "/files/" .. ngx.var.fname)
        if not img then ngx.exit(ngx.HTTP_NOT_FOUND) end
        img:set_gravity(magick.gravity["CenterGravity"])

        if string.match(ngx.var.h, "%d+%+") then
            local h = string.gsub(ngx.var.h, "(%+)", "")
            resize = ngx.var.w .. "x" .. h
            -- ╨┤╨╗╤П png ╤Б ╨░╨╗╤М╤Д╨░ ╨║╨░╨╜╨░╨╗╨╛╨╝
            img:set_bg_color(img:has_alphachannel() and "none" or img:get_bg_color())
            img:smart_resize(resize)
            img:extent(ngx.var.w, h)
        else
                img:smart_resize(ngx.var.w .. "x" .. ngx.var.h)
        end

        if ngx.var.arg_q then img:set_quality(ngx.var.q) end

        ngx.say(img:blob())
        ';
    }
}

# Upstream
upstream imageserver {
    server localhost:8082;
}

server {
    listen 80;
    server_name examaple.lh;

    # ╨╛╤В╨┐╤А╨░╨▓╨╗╤П╨╡╨╝ ╨▓╤Б╨╡ jpg ╨╕ png ╨║╨░╤А╤В╨╕╨╜╨║╨╕ ╨╜╨░ imageserver
    location ~* ^/files/.+.(jpg|png) {
        proxy_buffers 8 2m;
        proxy_buffer_size 10m;
        proxy_busy_buffers_size 10m;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass     http://imageserver;  # Backend image server
    }
}

рдЬреЗ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрддреЗ (рдХрдбрд╛рднреЛрд╡рддреА рдкреНрд░рддрд┐рдорд╛ рд╡рд┐рд╕реНрддреГрдд рдХрд░рдгреЗ) рд╡рд╛рдкрд░реВрди рд╣реЛрддреЗ img:extent() рдЖрдгрд┐ рдкреЕрд░рд╛рдореАрдЯрд░ рд╡рд╛рдкрд░реВрди рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреЗрд▓реЗ рдЖрд╣реЗ resize рдЪрд┐рдиреНрд╣рд╛рд╕рд╣ + рд╢реЗрд╡рдЯреА.

рдЦрд╛рд▓реАрд▓ рдкрд░реНрдпрд╛рдп рдЙрдкрд▓рдмреНрдз рдЖрд╣реЗрдд:

  • WxH (рдЖрд╕реНрдкреЗрдХреНрдЯ-рд░реЗрд╢реЛ рдареЗрд╡рд╛, рдЙрдЪреНрдЪ рдкрд░рд┐рдорд╛рдг рд╡рд╛рдкрд░рд╛)
  • WxH^ (рдЖрд╕реНрдкреЗрдХреНрдЯ-рд░реЗрд╢реЛ рдареЗрд╡рд╛, рд▓реЛрдЕрд░ рдбрд╛рдпрдореЗрдВрд╢рди рд╡рд╛рдкрд░рд╛ (рдкреАрдХ))
  • WxH! (рдЕрд╕реНрдкреЗрдХреНрдЯ-рд░реЗрд╢реЛ рджреБрд░реНрд▓рдХреНрд╖рд┐рдд рдХрд░рд╛)
  • WxH+ (рдЖрд╕реНрдкреЗрдХреНрдЯ-рд░реЗрд╢реЛ рдареЗрд╡рд╛, рдмрд╛рдЬреВрдЪреНрдпрд╛ рд╕реАрдорд╛ рдЬреЛрдбрд╛)

рдЖрдХрд╛рд░ рдмрджрд▓рд╛ рдкрд░рд┐рдгрд╛рдорд╛рдВрд╕рд╣ рд╕рд╛рд░рд╛рдВрд╢ рд╕рд╛рд░рдгреА

рдпреБрд░реА рдкреЕрд░рд╛рдореАрдЯрд░рдЪреА рд╡рд┐рдирдВрддреА рдХрд░рд╛
рдЖрдЙрдЯрдкреБрдЯ рдкреНрд░рддрд┐рдорд╛ рдЖрдХрд╛рд░

?resize=400├Ч200
200 ├Ч 200

?resize=400├Ч200^
400 ├Ч 400

?resize=400├Ч200!
400├Ч200 (рдкреНрд░рдорд╛рдгрд╛рдд рдирд╛рд╣реА)

?resize=400├Ч200+
400├Ч200 (рдкреНрд░рдорд╛рдгрд╛рдд)

Nginx рдЖрдгрд┐ LuaJIT (OpenResty) рд╡рд╛рдкрд░реВрди рдлреНрд▓рд╛рдпрд╡рд░ рдкреНрд░рддрд┐рдорд╛рдВрдЪрд╛ рдЖрдХрд╛рд░ рдмрджрд▓рд╛

рдкрд░рд┐рдгрд╛рдо

рдпрд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдирд╛рдЪреА рд╕рд╛рдорд░реНрдереНрдп рдЖрдгрд┐ рд╕рд╛рдзреЗрдкрдгрд╛ рд▓рдХреНрд╖рд╛рдд рдШреЗрдКрди, рдЖрдкрдг рдмрд░реНтАНрдпрд╛рдЪ рдЬрдЯрд┐рд▓ рддрд░реНрдХрд╛рдВрд╕рд╣ рдЧреЛрд╖реНрдЯреА рд▓рд╛рдЧреВ рдХрд░реВ рд╢рдХрддрд╛, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рд╡реЙрдЯрд░рдорд╛рд░реНрдХ рдЬреЛрдбрдгреЗ рдХрд┐рдВрд╡рд╛ рдорд░реНрдпрд╛рджрд┐рдд рдкреНрд░рд╡реЗрд╢рд╛рд╕рд╣ рдЕрдзрд┐рдХреГрддрддрд╛ рд▓рд╛рдЧреВ рдХрд░рдгреЗ. рдкреНрд░рддрд┐рдорд╛рдВрд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА API рдЪреА рдХреНрд╖рдорддрд╛ рд╢реЛрдзрдгреНрдпрд╛рд╕рд╛рдареА, рдЖрдкрдг рд▓рд╛рдпрдмреНрд░рд░реА рджрд╕реНрддрдРрд╡рдЬреАрдХрд░рдг рдкрд╛рд╣реВ рд╢рдХрддрд╛ isage/lua-imagick

рд╕реНрддреНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╛