I decided to use Python as a primary language on my starting up website. I'm pretty sure that uWSGI and Bottle framework work perfect together. I'm a little bit worry that they will serve static files slowly ( I experienced this problem in NodeJS ). Is it preferably to specify multiple uWSGI apps and point them to different directories that don't contain static files?
Will Nginx serve static files faster?
ROOT/
|--assets/
|----some.css
|----and_image.png
|--robots.txt
sign_in/
|--[application related files here]
sign_up/
|--[application related files here]
Web server's root is ROOT and application's and directories that contain files of application are outside the web server's root.
I suppose this will be better
location /sign-in {
uwsgi_pass unix:///run/uwsgi/app/sign-in/sign-in.co.socket;
include uwsgi_params;
uwsgi_param UWSGI_SCHEME $scheme;
uwsgi_param SERVER_SOFTWARE nginx/$nginx_version;
}
location /sign-up {
uwsgi_pass unix:///run/uwsgi/app/sign-up/sign-up.co.socket;
include uwsgi_params;
uwsgi_param UWSGI_SCHEME $scheme;
uwsgi_param SERVER_SOFTWARE nginx/$nginx_version;
}
than this:
location / {
uwsgi_pass unix:///run/uwsgi/app/whole-website/whole-website.co.socket;
include uwsgi_params;
uwsgi_param UWSGI_SCHEME $scheme;
uwsgi_param SERVER_SOFTWARE nginx/$nginx_version;
}
Is it really better? Or in this case uWSGI won't serve static files?
You want nginx to serve your static files. Given they are static, there's no logic required to serve them, unlike your templates/views in bottle. So its better for static file requests to never have to hit python. And its really easy to set up in nginx!
Inside your server block just add:
location /assets/ {
alias pathtoyourproject/ROOT/assets/;
}
Related
my application is working fine at
location / {
include uwsgi_params;
uwsgi_pass unix:/tmp/socket_file.sock;
}
but when i include static assets location location ~* .\(css|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rtf)it gives 404 not found error for css,js files
server {
listen 8080;
server_name your_domain www.your_domain;
location ~* \.(css|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rtf)$ {
expires max;
log_not_found off;
access_log off;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/tmp/socket_file.sock;
}
}
nginx error log show `
"/usr/share/nginx/html/static/js/jspdf.js" failed (2: No such file or directory)
'
While my static assets are in /ProjectDirectory/assets/
locations are mutually exclusive, i.e. only one may match at a time. When the first location (regex) matches, directives in the second location / are ignored, and Nginx will proceed with whatever defined outside of this location block (if not defined). In your case, it's apparent that root /usr/share/nginx/html is defined somewhere at an outer level.
A straightforward solution would be to add the same include and uwsgi_pass to the first location block, but since you're serving static files, why not let Nginx handle it by adding root /path/to/your/static/files?
In practice, instead of matching file extension by regex, it's better to put all your files in one location, and use prefix-based matching:
location /static/ {
alias /ProjectDirectory/assets/;
}
You might want to read this answer to learn about the differences between root and alias.
Background
A docker container running a supervisord process with 2 processes started - nginx and uwsgi (yes I understand this may be doing docker 'wrong'. That's not the question)
The uwsgi hits a python flask app. This has a logger connected, and prints the headers dictionary to the info log.
I have a postman request that tests from my local box, hits the docker container, routes via nginx and hits the python app, with the info log appended.
Custom headers sent by postman are being logged (thanks to ignore_invalid_headers off;)
The Problem
I'd like to use nginx to decorate incoming requests with some further headers. No matter what I try I can't get it to work. None of the headers I add in the nginx conf seems to make it through to the flask app.
I've tried proxy_set_header or uwgi_param. No variant seems to work.
Please note - I want a request header. I believe add_header is for response headers.
nginx.conf:
user nginx;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 768;
}
http {
include /etc/nginx/mime.types;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
underscores_in_headers off;
ignore_invalid_headers off;
upstream myapp {
server unix:/run/myapp.sock;
}
server {
listen 80;
location / {
include uwsgi_params;
uwsgi_pass myapp;
proxy_set_header x-proxy-set-header x-proxy-set-header-value;
proxy_set_header sampl-header ONE;
uwsgi_param X-add-uwsgi-param x-added-uwsfi-param-value;
}
}
}
daemon off;
Any help would be hugely appreciated!!
So. Solved. As Richard Smith also found- proxy_pass doesn't work as I'm using uwsgi_pass for the custom protocol.
SO. this works:
location / {
include uwsgi_params;
uwsgi_pass myapp;
uwsgi_pass_request_headers on;
uwsgi_param HTTP_X_TESTING 'bar';
}
And we're cooking on gas...
Air Punch
I am using this tutorial - part 1, but i am not sure how to test if the app is running with nginx serving static files or not.
I have exactly the same code.
/etc/nginx/sites-available/flask_project
server {
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /static {
alias /home/www/flask_project/static/;
}
}
And then:
gunicorn app:app -b localhost:8000
All routes are working fine. However if I do http://localhost:8000/static i will see
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
And apparently I should see the page with <h1>Test!</h1> from static folder.
What i am doing wrong?
Basically i want to know how configure nginx to serve static files and then confirm.
-app.py
-static
-index.html
First, requests to port 8000 completely bypass nginx, so nothing strange here. You should go to localhost without port number.
Second, you have to symlink this config to /etc/nginx/sites-enabled and reload nginx.
Third, your static location is wrong. You have location without trailing slash and alias with one. They should always be with or without trailing slash simultaneously. And in this case it's even better to have root directive.
server {
root /home/www/flask_project;
index index.html;
location / {
proxy_pass http://localhost:8000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /static/ {
# empty. Will serve static files from ROOT/static.
}
}
You should make request directly http://localhost:8000/static/index.html then you will see response.
But if you want to see on index.html by default, you should have something like in conf:
location /static {
alias /home/www/flask_project/static/;
try_files $uri $uri/index.html index.html;
}
I've spent many, many hours debugging this, and have not quite come to a solution yet. I've tried applying the solutions from the dozen or so relevant threads, but none solved the problem (that or I implemented the solution wrong).
I'm trying to serve media and static files using nginx and django, and am using a media file to test with (following this tutorial). The logs show that it's trying to grab the correct file, but it just doesn't have the permissions to do so (failed (13: Permission denied)). Everything is set to 755. My nginx.conf and mysite_nginx.conf are as follows. Any ideas?
nginx.conf
worker_processes 1;
error_log /usr/local/etc/nginx/logs/error.log debug;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /usr/local/etc/nginx/logs/access.log main;
sendfile on;
keepalive_timeout 65;
index index.html index.php;
include /usr/local/etc/nginx/sites-enabled/mysite_nginx.conf;
}
mysite_nginx.conf
upstream django {
server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
server {
listen 8000;
server_name localhost;
root /var/www/;
access_log /usr/local/etc/nginx/logs/default.access.log main;
location / { } #go to default index.html
location /media/ {
alias /Users/meep_me/Desktop/ram_stuff/combining/box/mysite/media/; # your Django project's media files
}
location /static/ {
alias /Users/meep_me/Desktop/ram_stuff/combining/box/mysite/static/; # your Django project's static files
}
location /other {
uwsgi_pass django;
include /Users/meep_me/Desktop/ram_stuff/combining/box/mysite/uwsgi_params; # the uwsgi_params file you installed
}
}
/Users/meep_me/Desktop/ram_stuff/combining/box/mysite/media/: Do each of the folders have the +x bit set for permissions (usually required to list/access a folder/subfolder)?
The fix was as mentioned by warath-coder in the comments. I forgot to explicitly make sure every single folder actually had the +x bit set. Going through and finding the one that didn't solved the issue.
Sorry for my poor english, I'm french... no one is perfect.
I'm trying to install ReviewBoard under Nginx (LEMP with Debian Wheezy, Nginx 1.4.5, MySQL 14.14, PHP 5.4.4). My python installation use Python 2.7.3, easy_install 0.6.24dev-r0, pip 1.1, virtualenv 1.11.4 and gunicorn 18.0.
I succeeded to install all that stuff and create a reviewboard site but I fail to access the reviewboard site from a browser.
I know that reviewboard recommends Apache but also that is possible to install it on Nginx. I can't find any step-by-step tutorial except many links to http: / /rramsden.ca/blog/2011/09/26/nginx-reviewboard/ but this link is dead. Does anyone know another link ?
My Nginx conf is:
server {
listen 80;
server_name review.unskontrollables.org;
root /var/www/review.unskontrollables.org/htdocs;
# Error handlers
error_page 500 502 503 504 /errordocs/500.html;
# serve directly - analogous for static/staticfiles
# Alias static media requests to filesystem
location /media {
alias /var/www/review.unskontrollables.org/htdocs/media;
# if asset versioning is used
if ($query_string) {
expires max;
}
}
location /static {
alias /var/www/review.unskontrollables.org/htdocs/static;
}
location /errordocs {
alias /var/www/review.unskontrollables.org/htdocs/errordocs;
}
location /favicon.ico {
alias /var/www/review.unskontrollables.org/htdocs/static/rb/images/favicon.png;
}
#~ location /admin/media/ {
#~ # this changes depending on your python version
#~ root /usr/local/lib/python2.6/site-packages/django/contrib;
#~ }
location / {
#alias /var/www/review.unskontrollables.org/htdocs/reviewboard.wsgi;
#root /var/www/review.unskontrollables.org/htdocs/reviewboard.wsgi/;
#proxy_pass_request_headers on;
proxy_pass_header Server;
proxy_set_header Host $proxy_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:8000/;
}
# Prevent the server from processing or allowing the rendering of
# certain file types.
location /media/uploaded {
types {
text/plain .html .htm .shtml .php .php3 .php4 .php5 .phps .asp .pl .py .fcgi .cgi .phtml .phtm .pht .jsp .sh .rb;
}
}
}
To launch the WSGI server, I use:
root#jotunn:~# source /opt/reviewboard/rbenv/bin/activate
(rbenv)root#jotunn:~# rb-site manage /var/www/review.unskontrollables.org/ runserver
Validating models...
0 errors found
Django version 1.4.10, using settings 'reviewboard.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
If I try to access
http://review.unskontrollables.org/
I'm redirected to
http://127.0.0.1:8000/r/
and the console output is:
/opt/reviewboard/rbenv/local/lib/python2.7/site-packages/Django-1.4.10-py2.7.egg/django/views/generic/list_detail.py:10: DeprecationWarning: Function-based generic views have been deprecated; use class-based views instead.
DeprecationWarning
/opt/reviewboard/rbenv/local/lib/python2.7/site-packages/Django-1.4.10-py2.7.egg/django/conf/__init__.py:75: DeprecationWarning: The ADMIN_MEDIA_PREFIX setting has been removed; use STATIC_URL instead.
"use STATIC_URL instead.", DeprecationWarning)
/opt/reviewboard/rbenv/local/lib/python2.7/site-packages/Django-1.4.10-py2.7.egg/django/views/generic/simple.py:8: DeprecationWarning: Function-based generic views have been deprecated; use class-based views instead.
DeprecationWarning
[14/Mar/2014 16:59:50] "GET / HTTP/1.0" 302 0
Does any one has an idea ?
Thanks.
EDIT: I found a solution based on the following tutorial
https://github.com/shuge/man/blob/master/sa/review/reviewboard/reviewboard-quick-install-guide.md
The missing link to the config file rb.m.com.conf point this file: https://github.com/shuge/man/blob/master/sa/review/reviewboard/rb.m.com.conf
With that data, I've just add flup (fastcgi python module) and changed my conf to the following:
server {
listen 80;
server_name review.unskontrollables.org;
root /var/www/review.unskontrollables.org/htdocs;
# Error handlers
error_page 500 502 503 504 /errordocs/500.html;
# serve directly - analogous for static/staticfiles
# Alias static media requests to filesystem
location /media {
alias /var/www/review.unskontrollables.org/htdocs/media;
# if asset versioning is used
if ($query_string) {
expires max;
}
}
location /static {
alias /var/www/review.unskontrollables.org/htdocs/static;
}
location /errordocs {
alias /var/www/review.unskontrollables.org/htdocs/errordocs;
}
location /favicon.ico {
alias /var/www/review.unskontrollables.org/htdocs/static/rb/images/favicon.png;
}
#~ location /admin/media/ {
#~ # this changes depending on your python version
#~ root /usr/local/lib/python2.6/site-packages/django/contrib;
#~ }
location / {
fastcgi_pass 127.0.0.1:9090;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_pass_header Authorization;
fastcgi_intercept_errors off;
}
# Prevent the server from processing or allowing the rendering of
# certain file types.
location /media/uploaded {
types {
text/plain .html .htm .shtml .php .php3 .php4 .php5 .phps .asp .pl .py .fcgi .cgi .phtml .phtm .pht .jsp .sh .rb;
}
}
}
After that nginx is restarted, everything works fine.