mikeboers / Flask-Images

On-demand resizing of images for Flask applications.
https://mikeboers.github.io/Flask-Images/
BSD 3-Clause "New" or "Revised" License
81 stars 43 forks source link

Serving images with nginx? #35

Closed vovanz closed 9 years ago

vovanz commented 9 years ago

How could I serve cached images as static files with nginx (or another webserver) after they was generated? Is it possible with Flask-Images ?

mikeboers commented 9 years ago

As things currently are, Flask-Images serves the images itself. It does so via Flask's sendfile, which does support the X-Sendfile header.

You could create a middleware that would translate the X-Sendfile to X-Accel-Redirect with an understanding of your server config; see this Flask issue.

Potentially, Flask-Images could be modified to immediately prepare an image, and return a public URL to it (given some extra configuration), but that may not be a simple change.

I think the most sensible thing to do is to move the sendfile call into a method of the Images class so that it is easy to override the behaviour.

iurisilvio commented 9 years ago

Of course you can use HTTP headers to handle it.

An other idea, you can just use nginx awesome internal cache, caching the /imgsizer path.

http://nginx.com/resources/admin-guide/caching/

mikeboers commented 9 years ago

If this works how I think it does (which is not likely given that I literally didn't read the page), then it would also be a good idea to turn off Flask-Image's caching as well. Then nginx is the only one who holds the actual data.

If someone sets this up please post the particulars as I would like to include it in the documentation.

iurisilvio commented 9 years ago

I don't use it for Flask-Images, but I use nginx caching for lots of things. I cache my assets and some slow pages with nginx.

uwsgi_cache_path /tmp/myapp/imgsizer/ keys_zone=imgsizer:10m
                 loader_threshold=300 loader_files=200 max_size=100m levels=1:2;
uwsgi_cache_valid 200 301 302 404 10m;
uwsgi_cache_key $host$request_uri;

server {
    server_name www.yoursite.com;
    listen 80;
    location /imgsizer/ {
        uwsgi_cache imgsizer;
        uwsgi_ignore_headers Set-Cookie;
        uwsgi_hide_header Set-Cookie;
        add_header X-Cache $upstream_cache_status;
        include uwsgi_params;
        uwsgi_pass localhost:8080;
    }
    location / {
        include uwsgi_params;
        uwsgi_pass localhost:8080;
    }
}

This example cache your /imgsizer/ path for 10 minutes (the 10m in uwsgi_cache_valid statement). If it is static images, you can use higher numbers. Nginx can serve some thousand requests/second. The nginx performance is wonderful.

Feel free to contact me if someone want help to make it happen, but I don't know how to write a generic example.

vovanz commented 9 years ago

@mikeboers @iurisilvio thanks for your answers! I will read more about X-Sendfile and nginx caching.