how to resolve nginx static assets not found error - python

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.

Related

How to use django-hosts with Nginx

I have created one Django app which has two apps named "api" and "consumer". Now I want to use subdomains for both of this app. Like api.server.com and server.com. I searched online and found django-hosts so I implemented in my localhost and its working fine.
After that I deployed it on AWS EC2 instance and created subdomain in Godaddy and point both root domain and subdomain to my instance IP. Root domain is working fine but when I try to go api.server.com, it shows me default Welcome to Nginx screen. Please help me with this issue.
nginx.conf
server{
server_name server.com, api.server.com;
access_log /var/log/nginx/example.log;
location /static/ {
alias /home/path/to/static/;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/username/project/project.sock;
}
}
You don't need the , a simple space will do.
server_name server.com api.server.com;
Also you can use wildcards, see the documentation.
server_name *.server.com;
You don't have to use a plugin (like django-hosts) to achieve what you are trying to do. Create 2 different nginx configurations for each subdomain you want to create (server.com and api.server.com), and forward requests from api.server.com to /api URL and request from server.com to /. Following is a basic example.
server.com
server {
listen 80;
server_name server.com;
location / {
proxy_pass http://127.0.0.1:3000$request_uri;
}
}
api.server.com
server {
listen 80;
server_name api.server.com;
location / {
proxy_pass http://127.0.0.1:3000/api$request_uri;
}
}
I recommend not to depend on 3rd party plugins unnecessarily. Refer https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/ for more details.

Nginx + Gunicorn - error pages for static resources

I am running a Python Flask application with Gunicorn and Nginx as a reverse proxy. Pages are served by Gunicorn and Nginx is serving files from my static folder directly.
It's working correctly except where I get a 404 on a static resources.
I have setup custom error handlers in Flask to show 'pretty' error pages on HTTP error codes. This is also working fine when I request a non-existent page.
However, when a static resource doesn't exist then nginx serves its own default 404 page instead of the Flask app's 404 page (which makes sense since it's bypassing Gunicorn). Is there a way to tell nginx to serve the Flask error handler page via Gunicorn if it encounters an error serving a static resource?
Here is my current nginx conf file for this server:
server {
listen 80;
server_name example.com;
access_log /home/aaron/dev/apwd-flask/logs/access.log;
error_log /home/aaron/dev/apwd-flask/logs/error.log;
location / {
include proxy_params;
proxy_pass http://localhost:8000;
}
location /static {
alias /home/aaron/dev/apwd-flask/app/static/;
}
}
I'm thinking (hoping) I can use an error_page directive to give control back to Gunicorn and tell it to serve the appropriate custom error handler, but haven't been able to figure out if that's possible or how to do it from the documentation.
Answering my own question as I was able to locate an answer to this after alot of searching so posting it here for the benefit of anyone else who may have the same issue. I expect this would work for any backend, not just gunicorn.
https://www.nginx.com/resources/admin-guide/serving-static-content/
In the section entitled 'Trying Several Options' the final example shows the solution to this problem, using the try_files directive in the static location block I can tell nginx to pass the request to a named location if it fails to find the requested file.
Here is my new nginx conf file which is working as expected now for non-existent static file requests:
server {
listen 80;
server_name example.com;
access_log /home/aaron/dev/apwd-flask/logs/access.log;
error_log /home/aaron/dev/apwd-flask/logs/error.log;
location #apwd_flask {
include proxy_params;
proxy_pass http://localhost:8000;
}
location / {
try_files $uri #apwd_flask;
}
location /static {
alias /home/aaron/dev/apwd-flask/app/static/;
try_files $uri #apwd_flask;
}
}
Now my location #apwd_flask is the gunicorn backend and when my static files aren't found by nginx serving directly, it sends the request to the backend which serves its own 404 response.
You need to change the owner of files in below directory
/home/aaron/dev/apwd-flask/app/static/
In order to give access to nginx user to read files in the static directory change the owner to www-data or change the owner group to www-data and give the read access to all files in this directory.
You can do this by running below command:
chown -R www-data:www-data /home/aaron/dev/apwd-flask/app/static/

NGINX/Django: 403 error when serving static files

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.

(nginx + uWSGI + Bottle) Serve static Files

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/;
}

how to configure nginx to serve specific django url path with another domain

I have configured nginx + uwsgi to serve foo.com, but foo.com/bar/ I want to serve it like bar.com
example:
foo.com/bar/test/ = bar.com/test/
also I want to make bar.com robots not allowed.
any suggestion?
Assuming you have foo.com configured as:
location / {
# your normal stuff
}
Something like this should work:
location / {
rewrite ^/bar/(.*)$ bar.com/$1? break;
}
For blocking robots, see this nginx forum entry.
server {
listen 80;
server_name foo.com;
root /full/server/path/to/foo/folder;
index index.html index.php;
# This redirects anyone that directly types "foo.com/bar/xyz to bar.com/xyz"
if ($request_uri ~ ^/bar(.*)$) {
return 301 http://bar.com$1;
# Alternative for old nginx versions
# rewrite ^ http://bar.com$1 redirect;
}
# foo.com location blocks go below
...
}
server {
listen 80;
server_name bar.com;
root /full/server/path/to/foo/bar/folder;
index index.html index.php;
# bar.com location blocks go below
...
}

Categories

Resources