python flask - how setup cache in nginx - python

I have a flask/nginx application and want to setup cache for 2 example url :
1. /category/apps-5.html
2. /product/test-product-sell-34690064571.html
my actual nginx config is this :
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443;
ssl on;
gzip on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/html text/css application/json application/javascript application/x-javascript text/javascript text/xml application/xml application/rss+xml application/atom+xml application/rdf+xml;
gzip_disable "MSIE [1-6]\.";
gzip_vary on;
server_name selfmarket.net www.selfmarket.net;
ssl_certificate /etc/letsencrypt/live/selfmarket.net/cert.pem; # path to your cacert.pem
ssl_certificate_key /etc/letsencrypt/live/selfmarket.net/privkey.pem; # path to your privkey.pem
fastcgi_param HTTPS on;
fastcgi_param HTTP_SCHEME https;
# Serve static files and uploads
location ^~ /static/ {
root /opt/master/app/;
}
location / {
proxy_pass 'http://127.0.0.1:8080/';
proxy_redirect off;
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_set_header X-Forwarded-Host $server_name;
}
}
How i can setup simple cache (expiry in 3 minutes) for my example urls ? is my first time when use nginx .. im very beginer, thank you

The best way to do this is to cache on the backend. Flask has a simple cache or you can use memcache. See the examples here, here, and here.
Also, if you really need to speed things up, you can use the built-in memcache support that NGINX has (although this might be too complex). See this doc for more details.
If you really want NGINX to do the caching, check out the official docs on the proxy_cache module. There is also a guide available here.

Related

Django | Static files served by nginx not used by Client

I have a django app, with the following settings for static files:
STATIC_DIR = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
STATICFILES_DIRS = [STATIC_DIR,]
STATIC_ROOT = '/opt/static/'
I am running django using the follwoing gunicorn command:
gunicorn evee.wsgi -b 0.0.0.0:8000.
I have configured nginx to serve the static files and ssl using the following conf:
server {
keepalive_timeout 5;
listen 443 ssl;
server_name api.home.com;
client_max_body_size 4G;
error_page 500 502 503 504 /500.html;
# path for static files
root /opt;
location / {
# checks for static file, if not found proxy to app
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Ssl off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Port 80;
proxy_set_header X-Forwarded-Proto $scheme;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://evee:8000;
}
}
Interesting part is that I am able to see the CSS in the client. For example, the request to https://secapi.ril.com/static/admin/css/base.css is successful and returns a 200 response. I can view all the static files at the URL mentioned, but django does not seem to use them. Have tried changing clients as well as private mode.
Am I doing something terribly wrong? This was working last time I checked.
Try adding static files path in your nginx config files as:
location /static/ {
alias /opt/static/;
}
Here mention complete path to your static folder. I guess in your case its /opt/static/
Here is how I solved this. Had to edit the nginx.conf file to configure an upstream instead of redirecting it to http directly and removed a few headers that were being set. No clue how different it is or why this works. The entire setup is running in Docker Swarm.
#### SECAPI #####
upstream app_server {
# for a TCP configuration
server evee:8000 fail_timeout=0;
}
server {
keepalive_timeout 5;
listen 443 ssl;
server_name api.home.com;
client_max_body_size 4G;
error_page 500 502 503 504 /500.html;
# path for static files
root /opt;
location / {
# checks for static file, if not found proxy to app
try_files $uri #proxy_to_app;
}
location #proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://app_server;
}
}

Redirect http to https with nginx instead of using django-sslify?

I tried to use django-sslify and django-secure to redirect all http requests to https, but i just can't get it to work. Is it a valid solution to redirect them with nginx instead, like it is shown here: link
Or, maybe someone could explain, what is wrong with my config right now:
Before i added "proxy_set_header Host $host;" to the second server block it redirected nicely, but forms wouldn't work, because the csrf protection threw referrer errors.
server {
listen 80;
server_name domain.com;
location /static {
alias /home/adrian/sites/www.domain.com/static;
}
location / {
proxy_set_header Host $host;
proxy_pass http://unix:/tmp/www.domain.com.socket;
}
}
server {
listen 200.200.200.200:443;
server_name domain.com;
location /static {
alias /home/adrian/sites/www.domain.com/static;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://unix:/tmp/www.domain.com.de.socket;
}
ssl on;
ssl_certificate /etc/nginx/ssl/ssl.crt;
ssl_certificate_key /etc/nginx/ssl/domain.com.de.key;
ssl_prefer_server_ciphers on;
}
Okay, never mind. Django-sslify just didn't work for some reason and so i retried django-secure with
proxy_set_header Host $host;
set and it did work like a charm. But i would really like to hear, if it would be better or more efficient to redirect with nginx and i will accept that answer. Thanks.

How to correctly set virtual hosts on Ningx?

Trying to setup Nginx handling 2 domains I stucked with some problems. While my setup with two domains works correctly with static html handling, tried to push forward and start two python apps behind Nginx. I tried with some differents wsgi containers, and different micro frameworks, but the problem is that Nginx can't handle virtual hosts, rather it serves only one app at both domain adresses.
Here is Nginx conf:
user www-data;
worker_processes 8;
pid /var/run/nginx.pid;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_names_hash_bucket_size 64;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
server {
listen 80;
server_name www.domainA.com;
root /var/www/domainA.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Originating-IP $remote_addr;
proxy_set_header HTTP_REMOTE_ADDR $remote_addr;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_set_header CLIENT_IP $remote_addr;
proxy_pass http://127.0.0.2:7000;
}
}
server {
listen 80;
server_name www.domainB.com;
root /var/www/domainB.com;
location / {
... ... blah blah...same story...except this proxy pass.....
proxy_pass http://127.0.0.1:5000;
}
}
}
Any help ?
EDIT:
Just tried to add empty server block as 1st block and it return 404.
Are these outward facing websites?
If you put the full ip in your listen clause you should start working correctly.
listen 512.548.595.485:80;
Right now you have the server ip for both sites which is causing a conflict.
Hope this helps.
In the senario where virtual hosts share an ip and port, nginx selects the right virtual host by comparing the Host header sent by the client to each servers' server_name entry. If you have curl use the following to see exactly what you're sending for the Host header:
curl -s --trace-ascii - http://www.domainA.com | grep 'Host:'
To make your server_name more flexible use the .example.com notation. This is shorthand for example.com and *.example.com. Or just add as many server_name entries as you need.
Next confirm your apps are listening on the right ips and ports. Shell into your server and try:
curl -I 'http://127.0.0.1:5000'
curl -I 'http://127.0.0.2:7000'
Finally I ended with such problem. In testing conditions I didn't add all flavours which would make Nginx satisfied. Then I found THIS LINK :
If the “Host” header field does not match a server name, NGINX will route the request to the default server for this port. The default server is the first one listed in the nginx.conf file. This will be overridden if the default_server parameter is set in the listen directive within a server context. An example is given below.
Nginx docs and tutorials are dispersed on few web locations so finding few doesn't mean that you got all answers you need.
I think, this is your solution. Create a BASH file whose name should be virtualhost.sh. Copy and paste the following code:
#!/bin/bash
domain=$1
root="/data/$domain"
block="/etc/nginx/sites-available/$domain"
# Create the Document Root directory
mkdir -p $root
# Assign ownership to your regular user account
chown -R $USER:$USER $root
# Create the Nginx server block file:
tee $block > /dev/null <<EOF
server {
listen 80;
listen [::]:80;
root /data/$domain;
index index.php index.html index.htm;
server_name $domain www.$domain;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
include fastcgi_params;
}
location ~ /\.ht {
access_log off;
log_not_found off;
deny all;
}
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
access_log off;
log_not_found off;
expires 30d;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
}
EOF
# Link to make it available
ln -s $block /etc/nginx/sites-enabled/
# Test configuration and reload if successful
nginx -t && service nginx reload
You need call this BASH file:
virtualhost.sh www.yourdomain.com

Nginx, uwsgi and flask does not display the css file

I have set up uwsgi and nginx to serve a flask website that I'm working on but it refuses to display the css file even though it appears in the body of the page correctly and I can view it. It does not change the styling of the page.
I use the following nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
sendfile on;
gzip on;
gzip_http_version 1.0;
gzip_proxied any;
gzip_min_length 500;
gzip_disable "MSIE [1-6]\.";
gzip_types text/plain text/xml text/css
text/comma-separated-values
text/javascript
application/x-javascript
application/atom+xml;
# Configuration containing list of application servers
upstream uwsgicluster {
server 127.0.0.1:8080;
# server 127.0.0.1:8081;
# ..
# .
}
# Configuration for Nginx
server {
# Running port
listen 80;
# Settings to by-pass for static files
location ^~ /static/ {
# Example:
# root /full/path/to/application/static/file/dir;
root /app/static/;
}
# Serve a static file (ex. favico) outside static dir.
location = /favico.ico {
root /app/favico.ico;
}
# Proxying connections to application servers
location / {
include uwsgi_params;
uwsgi_pass uwsgicluster;
proxy_redirect off;
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_set_header X-Forwarded-Host $server_name;
}
}
}

Django SSL Redirect snippet modification, not working as expected

I'm using Nginx as webserver, with a reverse proxy to a gunicorn django server.
I tried using the SSLRedirect snippet from here:
http://djangosnippets.org/snippets/85/
Because this snippet would always return false from is_secure() with my setup, resulting in a redirect loop, I had to make some changes.
SSL works, but when I access http://domain.net/main it doesn't redirect to https://domain.net/main. Isn't it supposed to do that?
Below outlines the modification I made:
if 'HTTP_X_FORWARDED_PROTOCOL' in request.META:
return True
And in my nginx conf (I only need SSL, http not required):
server {
listen 8888;
server_name domain.net;
ssl on;
ssl_certificate /path/to/domain.pem;
ssl_certificate_key /path/to/domain.key;
# serve directly - analogous for static/staticfiles
location /media/ {
root /path/to/root;
}
location /static/ {
root /path/to/root;
}
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
proxy_pass http://127.0.0.1:8881/;
# note this line
proxy_set_header X-Forwarded-Protocol https;
}
}
Just do it entirely with nginx. No need to involve Django at all:
server {
listen 80;
rewrite ^(.*) https://$host$1 permanent;
}
server {
listen 443;
# The rest of your original server config here
}

Categories

Resources