How to run django project on nginx and uwsgi - python

I'm trying to run my first Django project using nginx and uwsgi. And I faced with the problem with nginx. I get the message in the brouser "Unable to connect. Firefox can't establish a connection to the server at localhost:8000". I'm following the instructions from this link Everything is fine with uwsgi and installing nginx. Then I downloaded uwsgi_params file and created mysite_nginx.conf file as the instruction says.
Here's mysite_nginx.conf file:
# mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 8000;
# the domain name it will serve for
server_name localhost; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /home/ubuntu/myproject/mysite/friends_plans/media; # your Django project's media files - amend as required
}
location /static {
alias /home/ubuntu/myproject/mysite/friends_plans/static; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /home/ubuntu/myproject/mysite/uwsgi_params; # the uwsgi_params file you installed
}
}
It worked with server name "localhost" and port 8000 when I was checking uwsgi according to the intruction. I made the commands sudo ln -s ~/path/to/your/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/ , python manage.py collectstatic , sudo /etc/init.d/nginx restart. In my settinds.py: STATIC_ROOT = "/home/ubuntu/myproject/mysite/friends_plans/static/". The command about static files worked properly. But I can't set the connection with the server. Could you please tell me where I have a mistake and how to correct it? Thank you very much in advance.

Related

Forwarding Nginx port to gunicorn instance

I was following this tutorial to setup my flask server.
https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-18-04#step-6-%E2%80%94-securing-the-application
When I got to step 6 I see that they are setting flask for the whole url but I would like to point it to a specific port.
This is the code I have for my nginx which points. This currenly produces a 404.
server {
listen 5000;
server_name site.com;
location / {
include proxy_params;
proxy_pass http://unix:/home/user/project/project.sock;
}
}
All the other files are the same as the tutorial. I have tried to modify the .sock file but it seems like it was generated automatically and it can't be modified. In addition I need to find a way for nginx to handle this before I worry about handling it from gunicorn.
My end goal is to have nginx foward requests to flask running when a request is sent to 0.0.0.0:5000 and have all other requests 0.0.0.0 , 0.0.0.0/* be handled by nginx.
Any help to undestand all this is really appreciated got lost at this point.
EDIT
my nginx configuration in sites-available
server {
server_name domain www.domain;
location / {
include proxy_params;
proxy_pass http://127.0.0.1:8080/;
}
}
If you want flask to be open to a port instead of a file you should override
[service] to
[service]
...
ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind 127.0.0.1:8000 -m 007 wsgi:app
And change your nginx config to proxy_pass http://127.0.0.1:8000/;
This way you can have access to port 8000 for checking how are working gunicorn and flask. Remember to be careful with firewall rules to secure port 8000. For a good discussion on which one is better you can try: gunicorn + nginx: Server via socket or proxy?

uWSGI, nginx, django unix sockets not working

I have a django application. I can't seem to get nginx to serve the static files correctly, but that's not this issue.
The current issue is that when following this guide: https://gist.github.com/evildmp/3094281
I try to use the unix sockets rather than the web socket.
e.g.
server unix:///tmp/uwsgi.sock; # for a file socket
#server 127.0.0.1:8001; # for a web port socket
using the /tmp/uwsgi.sock socket rather than the 127.0.0.1:8001 web port socket.
The issue is that when I use the web port socket, and I navigate to domainname.com:8001 I reach the website as served by uWSGI, but there are no staticfiles loaded. So that means that at least uwsgi is working. But when I switch over to the file socket, I cannot even get it to work at all.
What am I doing wrong?
Here is my nginx.conf:
# nginx.conf
upstream django {
# connect to this socket
# server unix:///tmp/uwsgi.sock; # for a file socket (TRYING TO USE)
server 127.0.0.1:8001; # for a web port socket (RATHER THAN THIS)
}
server {
# the port your site will be served on
listen 8000;
# the domain name it will serve for
server_name .cshenkan.com; # substitute your machine's IP address or FQDN
charset utf-8;
#Max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /home/ubuntu/sasite-rewrite/media; # your Django pro$
}
location /static {
alias /home/ubuntu/sasite-rewrite/static; # your Django pro$
}
location /assets {
alias /home/ubuntu/sasite-rewrite/assets
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /etc/nginx/uwsgi_params; # or the uwsgi_params you installe$
}
}
And my base.py settings file snippet:
STATIC_ROOT = normpath(join(SITE_ROOT, 'static'))
STATIC_URL = '/static/'
STATICFILES_DIRS = (
normpath(join(SITE_ROOT, 'static')),
normpath(join(SITE_ROOT, 'assets')),
)
And how I run uwsgi when using the web socket:
uwsgi --http :8001 --chdir /home/ubuntu/sasite-rewrite --wsgi-file /home/ubuntu/sasite-rewrite/sasite/wsgi.py
And how I run it when using the unix socket:
uwsgi --socket /tmp/uwsgi.sock --chdir /home/ubutnu/sasite-rewrite --wsgi-file /home/ubuntu/sasite-rewrite/sasite/wsgi.py
I just can't seem to get it to work when using the unix socket.
Neither can I get nginx to serve the correct static files, for example if I add a file to the media directory called 1.png or 1.txt and try to access them with domainname.com:8000/media/1.png I always get a hang or a no response from server error.
What am I doing wrong?
How can I get the unix socket to work correctly? And is the command I'm using correct?
I also don't understand this, when I use the web socket, I can connect to domainname.com:8001 and get the page with no static files, it looks like crap but loads from uwsgi. But with the unix sockets I have no idea how to access the page served by uwsgi to see if it works with the unix socket. Before I can move onto getting nginx working, I need to solve this issue, as I tried using web sockets with nginx and still had no luck there, I'm hoping once my unix sockets are set up correctly nginx will work better.
Any suggestions, or examples you could provide? Would be much appreciated, I am a long time django programmer, but I have very rarely deployed the sites myself. So I am really struggling here.
Any help is much appreciated, thanks.
Today I had the same problem with NGINX + Socket Unix for uwsgi protocol.
I discovered that version 1.8 of the NGINX is bugged.
Try installing version 1.10 that will work via UNIX SOCKET.
If you use open-SuSE, you can get the rpm here:
http://download.opensuse.org/repositories/home:/ghostlyrat/openSUSE_Leap_42.2/x86_64/nginx-1.10.1-3.3.x86_64.rpm
Or, directly in the official nginx downloads area:
http://nginx.org/en/download.html

Nginx, django on ec2 with elastic ip not responding

I have a problem with my amazon ec2 instance. I cannot access my django application running on port 8004 from the browser.
I have setup an instance on amazon ec2, installed django and nginx. This is running on ubuntu trusty 14.04. I have a domain on external dns-nameserver and I have correctly pointed that domain to the public elastic ip of my amazon ec2 instance. When I ping the server it works and it shows the public ip.
I've seen similar threads before and in most cases problems with this have been because firewall rules have not been added for specific ports, that is they are not open to the outside world. In my case I made sure that port 22, 80 and 443 were open when I created the instance. I've even made ports 8000 - 8100 open.
Note: Eventually I will make django run with gunicorn but just to test it I'm simply running it by going: manage.py runserver 8004
Here is a snapshot of how my inbound rules look like for open ports on amazon ec2
Could it be because I'm editing inbound rules after I launched the instance? Isn't that what you're suppose to be able to do?
Nginx is running without problems, I'll post my config below. I have no idea why this doesn't work. I have followed any thread I find on the subject and nothing seems to fix it.
UPDATE: I can now confirm that I can access my django site directly through the ip, by going
ip:8004. So obviously this is not a problem with the ports but has likely something to do with nginx config or my DNS settings.
My nginx config (I've replaced ip's with x, and the domain with sub.domain.com. I then try to access the site from sub.domain.com)
upstream docko_server {
server 127.0.0.1:8004 fail_timeout=0;
}
server {
server_name sub.domain.com;
listen xx.xx.xx.xxx:80;
return 303 https://$host$request_uri;
}
# HTTPS server
#
server {
listen xx.xx.xx.xxx:443;
server_name sub.domain.com;
ssl on;
ssl_certificate ssl/server.crt;
ssl_certificate_key ssl/server.key;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
ssl_prefer_server_ciphers on;
client_max_body_size 25M;
access_log /webapps/docko/logs/nginx-access.log;
error_log /webapps/docko/logs/nginx-error.log;
location /assets/ {
alias /webapps/docko/docko/staticfiles/;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://docko_server;
break;
}
}
}
If you want to access the django dev server from the Internet through the port 8004 try:
manage.py runserver 0.0.0.0:8004
The dev server will only listen by default on 127.0.0.1.
However you won't need this if you get to the dev server through Nginx, i.e. you connect to your.domain.com:80. In this case Nginx will act as a proxy, passing the request to the dev server.
BTW you can edit the rules of existing security group after launching the instances, this works perfectly.
To answer my own question I succeeded by not assigning the elastic ip but simply just listening on port 80, 443. So in my nginx conf instead of this.
server_name sub.domain.com;
listen xx.xx.xx.xxx:80;
I now just have
server_name sub.domain.com
listen 80;
same for 443.

403 Forbidden: Nginx not serving statics in Django Admin panel

settings.py
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
DEBUG = True
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'adminstatic')
mynginx.conf /etc/nginx/sites-enabled/mynginx.conf
you can be sure that I have only this conf file in sites-enabled folder
server {
listen *:80;
server_name _;
access_log /var/log/myapp.access.log;
error_log /var/log/myapp.error.log;
# Django media
location /static/ {
alias /root/proj/myapp/adminstatic/; #your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass unix:/tmp/myapp.sock;
include /etc/nginx/uwsgi_params; # the uwsgi_params file you installed
}
}
after this I tried collectstatic command
python manage.py collectstatic
It has succesfully collected all the statics in adminstatic folder.I crosscheked, there is a folder named admin in adminstatic folder. and this admin folder has 3 folders named css,img,js.
all these I'm doing in production machine. so when I tried to access the django admin page on my local browser by production's ip, the admin panel is opening but with loading any css/js. I did F12 and see in network tab. there was forbidden error for all statics.
PS: I'm using uWsgi along with nginx.
and as usual I've already looked at few SO threads and blogs. but it didn't help me.
The nginx web process user (usually www-data) probably doesn't have read permission of /root/proj/myapp/adminstatic/. I imagine if you check your myapp.error.log you would see permission denied messages.
You'd need to move your project into a folder the nginx process has permission to read from (you really shouldn't serve these things from /root) or you could chown / chmod /root/proj/myapp/adminstatic/ appropriately to give access to www-data.
I moved my static files to /data/www and it worked.
Move your project to /var/www/html/then run sudo chown -R www-data:www-data project-directory/ .Remember to edit your configurations on /etc/systemd/system/gunicorn.service and /etc/nginx/sites-available/your-project.conf to pint to the new location.
Then run
sudo systemctl daemon-reload,
sudo systemctl restart gunicorn,
sudo systemctl restart nginx

How do I set subdirectory in nginx with Django

Environment:
uwsgi
nginx
django 1.3
I'm using the domain www.example.com with Django and nginx, and I want to access the Django by www.example.com/abc/ , but I don't know how to set the subdirectory.
This is the nginx conf file:
server {
listen 80;
server_name www.example.com;
error_log /var/log/nginx/xxx.error_log info;
root /home/web/abc; # this is the directory of the django program
location ~* ^.+\.(jpg|jpeg|png|gif|css|js|ico){
root /home/web/abc;
access_log off;
expires 1h;
}
location ~ /abc/ { # I want to bind the django program to the domian's subdirectory
include uwsgi_params;
uwsgi_pass 127.0.0.1:9000;
}
}
When I open the website www.example.com/abc/, the django urls.py doesn't match, it only match the site like ^index$.
How can I modify the nginx location to set django to www.example.com/abc?
According to the uWSGI on Nginx docs, you just have to pass the SCRIPT_NAME to django.
location /abc {
include uwsgi_params;
uwsgi_pass 127.0.0.1:9000;
uwsgi_param SCRIPT_NAME /abc;
}
Django will still "see" /abc, but it should deal with it so that it gets stripped off before your urls are matched. You want this to happen, if django didn't see /abc, it would generate incorrect urls for your site and none of your links would work.
Now that uwsgi_modifier1 30 is removed in the latest versions of Nginx and uWSGI, I had to use a newer method to get it working:
uWSGI config:
[uwsgi]
route-run = fixpathinfo:
Nginx config:
location /abc {
include uwsgi_params;
uwsgi_pass 127.0.0.1:9000;
uwsgi_param SCRIPT_NAME /abc; # Pass the URL prefix to uWSGI so the "fixpathinfo:" route-rule can strip it out
}
IF THAT DOESN'T FIX IT: Try installing libpcre and libpcre-dev, then reinstall uwsgi with pip install -I --no-cache-dir uwsgi. uWSGI's internal routing subsystem requires the PCRE library to be installed before uWSGI is compiled/installed. More information on uWSGI and PCRE.

Categories