📜 ⬆️ ⬇️

Thumbnail Generator from Nginx

So, today we are going to assemble a miniatures generator based on the web server our people love - nginx. What is remarkable, we will do it without a single nail, i.e. without a single line of code, not counting the configuration.

The old school tells us to generate all the necessary miniatures immediately after loading the base image. The method is proven and reliable, however, we live in a volatile new world, in which we may need a new miniature size from Monday morning. Therefore, we will generate miniatures on the fly, upon request.

For the case, we need ngx_http_image_filter_module , a module that can transform images in JPEG, GIF and PNG formats. The module is standard, but not compiled by default, so you need to add it before building the nginka:
./configure --with-http_image_filter_module
Now we put libgd in the way we used in the system and collect the nginks. By the way, when building from FreeBSD ports, just run make config and select the required module in the list.

Just a pinch
For simplicity, we assume that we have a domain images.domain.ru, from which images are displayed lying in / path / to / images. Requests to /some/image.jpg will be issued directly, to /120x90/some/image.jpg or /120x-/some/image.jpg will be /120x-/some/image.jpg in miniatures (in the second case, the width is scaled only). In this case, we obtain:
server {
server_name images.domain.ru;
root /path/to/images;

if ($uri ~ ^/(\d+|-)x(\d+|-)/) {
set $w $1;
set $h $2;
}

location / {
}

location ~ ^/(?:\d+|-)x(?:\d+|-)/.*\.(?:jpg|gif|png)$ {
rewrite ^/[\w\d-]+/(.*)$ /$1;
image_filter resize $w $h;
break;
}
}

What's going on here? First, we determine the size of the thumbnail and set the corresponding variables. Then, we issue a static and proceed to the issue of miniatures, consider the second location in more detail: rewrite redirects the url to the real file, image_filter reduces the resulting image, break prevents internal redirection from exiting the location . The latter is important, otherwise the nginx will go all the way again with the already rewritten URL and will give a complete picture.
')
You can add predefined sizes:
if ($uri ~ ^/small/) {
set $w 120;
set $h 90;
}

location ~ ^/(?:\d+|-)x(?:\d+|-)|small/.*\.(?:jpg|gif|png)$ {
...

You can already use this if you don’t feel sorry for the processor, by the way, on FreeBSD 8 / Core 2 Quad Q9550 @ 2.83GHz / DDR2-800, you were able to pinch 200 images per second (jpeg, 640x480 -> 150x150). But, of course, we feel sorry for the processor, so we will cache the compressed images.

Pushes caching
Ngx_http_proxy_module deals with caching in the nginx, it caches only what it proxies, so we need to twist it out - we will listen to two ports and proxy ourselves:
proxy_cache_path /path/to/cache levels=1:2 keys_zone=thumbs:10m inactive=24h max_size=5G;

server {
server_name images.domain.ru;

location ~ ^/(?:\d+|-)x(?:\d+|-)|small/ {
proxy_pass http://localhost:8081;
proxy_cache thumbs;
proxy_cache_valid 200 24h;
proxy_cache_valid 404 415 1m;
}

location / {
root /path/to/images;
}
}

server {
listen 8081;

... ...
}

Done, now on the aforementioned system, the nginx gives out 15,000 pictures per second, if everything is out of cache, it's damn fast. I will not paint the settings, they are well painted in the documentation module . A full config can be taken here .

Source: https://habr.com/ru/post/94435/


All Articles