sysr-q/flask-themes2

How to server the static files with nginx?

sh4nks opened this issue · 11 comments

How can I serve the static files with nginx?

The static files for the the theme. Let say I have a theme named bootstrap2, than I would have the following folder structure:

themes/
    bootstrap2/
        static/
            css/
                main.css
        templates/
            layout.html
        info.json

And now, I want that the main.css file is served from nginx because he can do that much better than e.g. uWSGI.

Is this even possible?

Because of the dynamic-ish nature of how they're served by the app, I don't believe it's entirely possible without rewriting some of Flask-Themes2.
Things are served out of /_theme by default (if memory serves correct), which magically knows what to give to the user. It may well be possible (and might be a decent idea) to make it serve /_theme/<theme_name>, so you could use a better method of serving static files, but at the current point in time it's not really possible.
Shame though, it would be nice.

I had a look again, because I haven't worked on this in ages and - it turns out that static is served out of /_themes/<theme_name>/<static_file> (e.g in the example /_themes/calmblue/styles.css).
This means if you do something like:

location ~ ^/_themes/([^/]+)/ {
    alias /path/to/app/themes/$1/static/;
}

then hitting /_themes/calmblue/styles.css should serve /path/to/app/themes/calmblue/static/styles.css (through nginx). My nginx conf might be a bit off, but it appears to be possible.

Ah great! I will try this tomorrow :)

Sorry for my late reply.. I somehow forgot about this 😳

nginx always appends a "/" to the end, although I have removed the last slash from your example.

This is how my nginx config looks like now:

server {
    listen 80;
    server_name forums.flaskbb.org;

    access_log /var/log/nginx/access.forums.flaskbb.log;
    error_log /var/log/nginx/error.forums.flaskbb.log;

    location / {
        try_files $uri @flaskbb;
    }

    # Static files
    location /static {
       alias /var/apps/flaskbb/flaskbb/static/;
    }

    location ~ ^/_themes/([^/]+) {
        alias /var/apps/flaskbb/flaskbb/themes/$1/static/;
    }

    # TODO: robots.txt
    location /robots.txt {
        alias /var/apps/flaskbb/flaskbb/static/robots.txt;
    }

    location @flaskbb {
        uwsgi_pass 127.0.0.1:30002;
        include uwsgi_params;
    }
}

btw, you can test it here http://forums.flaskbb.org/_themes/bootstrap3/css/bootstrap.min.css

After a bit of trail and error I fixed it by myself.

my themes location now looks like this:

    location ~ ^/_themes/([.*]+) {
        alias /var/apps/flaskbb/flaskbb/themes/$1/static/;
    }

([.*]+) - does that work how you'd want it to though? Shouldn't that match... Any number of stars and dots? Those get escapes in character classes I thought.
As long as it works, I guess.

I'm pretty a noob in regex..

I got this idea from here and thought what happens If I replace ^/ with .* it and it worked. I just figured out, when now add a slash to the end, it also works. I don't really know why it didn't work last time.

How can I check if those files are really served via nginx?
After checking my uwsgi log, I get the feeling that it's served from uwsgi
{46 vars in 852 bytes} [Sat Feb 15 11:04:17 2014] GET /_themes/bootstrap3/css/flaskbb.css => generated 0 bytes in 3 msecs (HTTP/1.1 304) 4 headers in 189 bytes (0 switches on core 0)
Because, when I revert it back to ^/ these logs don't appear.

Thanks for taking your time!

Assuming your nginx install is the same as mine, you'd check wherever your access.log is for your site (/var/log/nginx/access.forums.flaskbb.log, according to your config, right?).
That'll have something like:
98.xxx.yyy.zzz - - [15/Feb/2014:00:51:28 +0000] "GET /something/static.css HTTP/1.1" 200 9990 "http://your-site.org/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:27.0) Gecko/20100101 Firefox/27.0"
If nginx is serving it, at least. If uwsgi is showing serve logs, it's not getting picked up by nginx, which probably means your regex is off, yeah.

I had another look at the nginx wiki and their example is:

location ~ ^/download/(.*)$ {
  alias /home/website/files/$1;
}

So would something like this work, perhaps? I'm really not 100% myself, and don't have an app set up I can test with on my box.

location ~ ^/_themes/([^/]+)/(.*)$ {
    alias /path/to/app/themes/$1/static/$2;

That worked! 😄
Now, I only have this in my uwsgi.log for one request.

{40 vars in 684 bytes} [Sat Feb 15 12:27:57 2014] GET / => generated 9445 bytes in 63 msecs (HTTP/1.1 200) 2 headers in 81 bytes (1 switches on core 0)

Thanks!

No worries. Good to see it worked, I might add that to the README/GitHub Wiki at some point.