Testing my Django app with uWSGI - django

I have written a uWSGI config file for my application that I'm trying to deploy on a production env.
myapp_wsgi.ini:
[uwsgi]
uid = www-data
gid = www-data
userhome = /home/glide
chdir = %(userhome)/myapp
module = myapp.wsgi
virtualenv = %(userhome)/.virtualenvs/myapp
env = DJANGO_SETTINGS_MODULE=myapp.settings
master = true
processes = 4
socket = /tmp/%n.sock
buffer-size = 32768
req-logger = file:/var/log/uwsgi/access.log
logger = file:/var/log/uwsgi/error.log
touch-reload = .git/index
enable-threads = true
As I'm not able to make it work beside my vassals (emperor mode I don't even see it loaded in the log, even by sending SIGHUP to the emperor process) I'm trying to check my configuration directly with uwsgi:
$ uwsgi myapp_uwsgi.ini
[uWSGI] getting INI configuration from myapp_uwsgi.ini
But it simply hangs there with no more message, nothing is appended to the error log.
I'm sure it's an expected behavior and I'm not looking in the right direction but I didn't have the courage to read the entire uWSGI doc which is quite generous.
So the question is how can I check my configuration ?
On the other hand, I also configured a vhost with NginX which logs me
*82 connect() to unix:///tmp/myapp.sock failed (111: Connection refused) while connecting to upstream, client: xxx.xxx.xxx.xxx, server: myapp.myhost.eu, request: "GET /favicon.ico HTTP/1.1", upstream: "uwsgi://unix:///tmp/myapp.sock:", host: "myapp.myhost.eu"
when I'm soliciting it

I had several things badly configured primarily the socket permission and some other small things.
That's why my Nginx was not able to talk to uWGSI.
This really good uWSGI howto Django & NginX helped me a lot to make work.

Related

how can i use uwsgi listen 80 port directly while deploying the django?

I am learning django, and now i have some trouble here. django cant receive the http packet but uwsgi packet from uwsgi server
when i write the configure file like this, it works.
[uwsgi]
http = xxx.xxx.xxx.xxx:9999
chdir = /home/ZoroGH/code/django/mysite1
wsgi-file = mysite1/wsgi.py
process=4
threads=2
pidfile=uwsgi.pid
daemonize=uwsgi.log
master=true
i can visit the IP:9999.
however, i cant change the port to 80, the log file says Permission Denied. then i enter sudo -i . in this mode ,the bash can't konw the uwsgi command.so i am here looking for help.
how can i use uwsgi listen 80 port directly?
i have made some search that some solutions are to use the nginx to pass the http to uwsgi service, but now i just want to only use the uwsgi to test my site. can it work?
i looked the document of uwsgi, it says never to use root mode to execute the uwsgi service, but to use the uid & gid ? sadly, i konw nothing about the uid & gid.
help me please

uWSGI as HTTP server: in config.ini option is called `http-socket`, not `http`

I'm trying to use uWSGI as a standalone http server, not a uwsgi server.
Here' my configuration file mysite.ini:
[uwsgi]
chdir = /srv/workflows
module = workflows.wsgi:application
plugin = python
# We can receive connections either via http or from frontend via uwsgi socket
# http:
http = 0.0.0.0:8000
# uwsgi:
#socket = 0.0.0.0:8000
#chmod-socket = 664
vacuum = true
master = true
need-app = true
processes = 10
harakiri = 20
max-requests = 5000
So, I used http option and commented-out socket and chmod-socket options.
In response to that uWSGI curses:
uWSGI: --s/--socket option is missing and stdin is not a socket.
Do I understand it right, that if I specify socket option, uWSGI expects connection to implement WSGI protocol? And if I specify http option, it expects connection to be http and I shouldn't specify the socket option in that case.
Try http-socket rather than http
Official documents recommend using http for a public server and http-socket for web-server after Nginx or Apache if you want use http in network.
https://uwsgi-docs.readthedocs.io/en/latest/ThingsToKnow.html
for me, HTTP works fine rather than the socket for TCP connection
example: http = 127.0.0.1:8080

Bad Request (400) after making supervisor restart

After restarting my django app: supervisorctl restart [process] I've got Bad Request(400) error when visiting my site. The app is under nginx with gunicorn and supervisor.
I remember to had the same problem some time ago and restarting supervisor from some specific folder on the server had helped. I've tried to restart supervisor from different locations, however it doesn't help.
nginx-error.log
2014/04/08 06:45:23 [error] 9635#0: *9 connect() to
unix:/webapps/filmyposlowie/run/gunicorn.sock failed (111: Connection
refused) while connecting to upstream, client: 78.10.91.212, server:
filmyposlowie.pl, request: "GET / HTTP/1.1", upstream:
"http://unix:/webapps/filmyposlowie/run/gunicorn.sock:/", host:
"filmyposlowie.pl"
I have the same issue, I solved it by adding these two lines in my nginx's server config file
proxy_set_header Host $http_host;
proxy_redirect off;
When you change DEBUG setting to False, you must also set ALLOWED_HOSTS.
You may simply make Django accept requests by allowing localhost:
ALLOWED_HOSTS = ['127.0.0.1']
This will work if gunicorn is running on same machine and it is bound to 127.0.0.1
Ref: DEBUG
Finally, if DEBUG is False, you also need to properly set the
ALLOWED_HOSTS setting. Failing to do so will result in all requests
being returned as “Bad Request (400)”.
I've changed DEBUG to True in settings.py of my django project and it works fine now.

Permission denied - nginx and uwsgi socket

Well I am currently trying to get my django application served using nginx and uwsgi. I am currently using a virtual environment to which uwsgi is installed. However I am currently getting a 502 bad gateway error when attempting to access the page.
The Error I am experiencing.
2014/02/27 14:20:48 [crit] 29947#0: *20 connect() to unix:///tmp/uwsgi.sock failed (13: Permission denied) while connecting to upstream, client: 144.136.65.176, server: domainname.com.au, request: "GET /favicon.ico HTTP/1.1", upstream: "uwsgi://unix:///tmp/uwsgi.sock:", host: "www.domainname.com.au"
This is my nginx.conf
# mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
server unix:///tmp/uwsgi.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 80;
# the domain name it will serve for
server_name .domainname.com.au; # 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/deepc/media; # your Django project's media files - amend as required
}
location /static {
alias /home/deepc/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/deepc/.virtualenvs/dcwebproj/dcweb/uwsgi_params; # the uwsgi_params file you installed
}
}
Here is my uwsgi.ini file
[uwsgi]
socket=/tmp/uwsgi.sock
chmod-socket=644
uid = www-data
gid = www-data
chdir=/home/deepc/.virtualenvs/dcwebproj/dcweb
module=dcweb.wsgi:application
pidfile=/home/deepc/.virtualenvs/dcwebproj/dcweb.pid
vacuum=true
From what i have read on google its a permissions problem with the www-data group and /tmp/ directory. However I am new to this and have tried to changer the permission level of the folder to no avail. Could someone point me in the right direction? Is this a permissions problem.
Also is it ok practice to put the sock file in tmp directory?
Thanks
I think you just need to change your socket file to 666(664 is ok with www-data), or remove it and run uwsgi server again.
In my uwsgi.ini:
chmod-socket = 664
uid = www-data
gid = www-data
Wow, this problem takes me almost a whole day!
I use uwsgi 2.0.14, nginx 1.10.1, django 1.10
To sum up, the most important thing is to make sure both of below two users have rwx permission to socket file:
the user of nginx;
the user of uWSGI;
So, you can check them one by one.
First you can check if the web server nginx has permission by refreshing the url, say http://192.168.201.210:8024/morning/, without running uwsgi. If you see /var/log/nginx/error.log No such file or directory, like this:
2016/10/14 16:53:49 [crit] 17099#0: *19 connect() to unix:///usr/share/nginx/html/test/helloworld.sock failed (2: No such file or directory) while connecting to upstream, client: 192.168.201.140, server: belter-tuesday.com, request: "GET /morning/ HTTP/1.1", upstream: "uwsgi://unix:///usr/share/nginx/html/test/helloworld.sock:", host: "192.168.201.210:8024"
Just create a file named helloworld.sock, and refresh the url and check log file again, if you see Permission denied in log file, like this:
2016/10/14 17:00:45 [crit] 17099#0: *22 connect() to unix:///usr/share/nginx/html/test/helloworld.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.201.140, server: belter-tuesday.com, request: "GET /morning/ HTTP/1.1", upstream: "uwsgi://unix:///usr/share/nginx/html/test/helloworld.sock:", host: "192.168.201.210:8024"
It means web server nginx does not have all permission to read, write and execute. So you can grant permission to this file:
sudo chmod 0777 helloworld.sock
Then, refresh the url and check log file again, if you see Connection refused
in log file, like this:
2016/10/14 17:09:28 [error] 17099#0: *25 connect() to unix:///usr/share/nginx/html/test/helloworld.sock failed (111: Connection refused) while connecting to upstream, client: 192.168.201.140, server: belter-tuesday.com, request: "GET /morning/ HTTP/1.1", upstream: "uwsgi://unix:///usr/share/nginx/html/test/helloworld.sock:", host: "192.168.201.210:8024"
This is a good sign, it means your web server nginx has the permission to use helloworld.sock file from now on.
Next to run uwsgi and check if the user of uwsgi has permission to use helloworld.sock. Firstly, remove the file helloworld.sock we have created before.
Run uwsgi: uwsgi --socket /usr/share/nginx/html/test/helloworld.sock --wsgi-file wsgi.py
If you see bind(): Permission denied [core/socket.c line 230], it means uwsgi don't have permission to bind helloworld.sock. This is the problem of the directory test, the parent directory of helloworld.sock.
sudo chmod 0777 test/
Now, you can run uwsgi successful.
But maybe you still see 502 Bad Gateway, it's terrible, I have seen it all day. If you check error.log file again, you will see this again:
2016/10/14 17:33:00 [crit] 17099#0: *28 connect() to unix:///usr/share/nginx/html/test/helloworld.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.201.140, server: belter-tuesday.com, request: "GET /morning/ HTTP/1.1", upstream: "uwsgi://unix:///usr/share/nginx/html/test/helloworld.sock:", host: "192.168.201.210:8024"
What's wrong???
Check the detail of helloworld.sock file, you can see:
srwxr-xr-x. 1 belter mslab 0 Oct 14 17:32 helloworld.sock
uWSGI gives this file 755 permission automatically.
You can change it by adding --chmod-socket:
uwsgi --socket /usr/share/nginx/html/test/helloworld.sock --wsgi-file wsgi.py --chmod-socket=777
OK! Finally, you can see:
Take away message:
uwsgi_params file's location is not important;
Since my nginx user and uwsgi user not same and even not at the same group, so I need to give 777 permission to helloworld.sock and its parent dir test/;
If you put helloworld.sock file in your home directory, you'll always get Permission denied.
There are two places you need to set the socket file path, one in nginx conf file, for me it is helloworld_nginx.conf; one when you run uwsgi.
Check SELinux
This is my helloworld_nginx.conf file:
# helloworld_nginx.conf
upstream django {
server unix:///usr/share/nginx/html/test/helloworld.sock; # for a file socket
# server 127.0.0.1:5902; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 8024;
# the domain name it will serve for
server_name .belter-tuesday.com; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Finally, send all non-media requests to the Django server.
location /morning {
include uwsgi_params;
uwsgi_pass django;
}
}
On CentOS, I tried all those things but still it did not work. Finally, I found this article:
https://www.nginx.com/blog/nginx-se-linux-changes-upgrading-rhel-6-6/
For a development machine, we simply run:
semanage permissive -a httpd_t
But for a real production server, I have not figured out.
You may need to try other things described in the above article.
This is take me a lot of time to find the problem with permissions.
And the problem is with permissions of course.
Default user is nginx.
What i did:
in /etc/nginx/nginx.conf change user:
user www-data;
Next join your user to www-data goup:
usermod -a -G www-data yourusername
Next set uwsgi:
[uwsgi]
uid = yourusername
gid = www-data
chmod-socket = 660
And then restart nginx:
sudo systemctl restart nginx
And finaly restart uwsgi.
I grappled with this problem for a while, and found that the uid and gid flags from my uwsgi.ini file were not being applied to the .sock file
You can test this by running uwsgi, then checking the permissions on your .sock file using the linux command ls -l.
The solution for me was to run uwsgi with sudo:
sudo uwsgi --ini mysite_uwsgi.ini
with the .ini file containing the flags:
chmod-socket = 664
uid = www-data
gid = www-data
Then the permissions on the .sock file were correct, and the 502 Bad Gateway error finally vanished!
Hope this helps :)
This issue made me crazy. My environment is centos7+nginx+uwsgi, using unix socket connection.
The accepted answer is awesome, just add some points in there.
ROOT USER, QUICK TEST
First, turn off selinux, then change chmod-socket to 666, and finally start uwsgi using root.
Like this
setenforce 0 #turn off selinux
chmod-socket = 666
uwsgi --ini uwsgi.ini
OTHER USER
If you use the other user you created to start uwsgi, make sure that the permissions of the user folder under the home folder are 755, and that the owner and the group are corresponding.
For example
chmod-socket = 666
usermod -a -G nginx webuser #add webuser to nginx's group
cd /home/
chmod -R 755 webuser
chown -R webuser:webuser webuser
uwsgi --ini uwsgi.ini --gid webuser --uid webuser
Another great article for CentOS users:
https://axilleas.me/en/blog/2013/selinux-policy-for-nginx-and-gitlab-unix-socket-in-fedora-19/
Although answers are useful regarding CentOS the problem lies beneath SELinux.
I followed the entire article but what solved the issue I believed where the following commands:
yum install -y policycoreutils-{python,devel}
grep nginx /var/log/audit/audit.log | audit2allow -M nginx
semodule -i nginx.pp
usermod -a -G user nginx
chmod g+rx /home/user/
Please substitute user with your actual user for granting permissions. Same applies for the directory under chmod command.
uwsgi.ini
[uwsgi]
uid = yourusername
gid = www-data
chmod-socket = 664
Why? Because sometimes the app needs to read or write to the file system beyond what's accessible to the web server. I don't want to change a whole bunch of ownership and permissions just to accommodate each such situation. I'd rather have my application run as me and do what it needs to do. Setting the group as www-data and chmoding the socket to 664 allows for that group to write to it, thus providing the only necessary window of communication between the web server and the app.
In dev mode, if using root, simply set wsgi.ini or emperor.ini as below:
uid=root
gid=root
you need to uncomment
#server 127.0.0.1:8001;
from upstream block and similarly do the changes in uwsgi.ini as
socket = 127.0.0.1:8001

502 error after adding application to a Django project running on nginx and gunicorn

I am trying to add an application to an existing Django project, but once I have done it I get a 502 error.The server is running Ubuntu. I don't think it has to do with the applications code because I got it running on the django development server. It goes away when I take out the app's name from settings.py and restart gunicorn.
Here's a part of the log
2011/07/15 01:24:45 [error] 16136#0: *75593 connect() failed (111: Connection refused) while connecting to upstream, client: 24.17.8.152, server: staging.site.org, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8020/", host: "staging.site.org"
Here's the nginx config file.
Nginx Config File
I'm not sure what other information is needed. Not sure where the gunicorn logs are located. My server admin skills are kind of lacking.
Nginx isn't able to connect to your backend (gunicorn) or gunicorn is refusing the connection. You provided no details about the configuration so that's all the help you'll get. You are correct that the application code has nothing to do with it. It's a configuration error on your part.