nginx Permission denied on Ubuntu - django

I'm trying to set up my Django app with uWSGI and nginx by following this guide. I'm able to run my app with Django's development server, as well as being served directly from uWSGI.
I'm running everything on a university managed Ubuntu 16.04 virtual machine, and my user has sudo access.
My problem:
When getting to this bit of the tutorial, and try to fetch an image, I get a 403 error from nginx.
The next section results in a 502.
/var/log/nginx/error.log shows
connect() to unix:///me/myproject/media/image.jpg failed (13: Permission denied) while connecting to upstream
connect() to unix:///me/myproject/project.sock failed (13: Permission denied) while connecting to upstream
for the 403 and 502, respectively.
I have read multiple questions and guides (one here, another here and yet another one, and this is not all of them), changed my permissions and even moved my .sock to another folder (one of the SO answers recommended that).
What else can I try?
Update:
I mentioned it in a comment, but I've gotten a bit further. A part of the problem was that, apparently, the /home directory on my VM is NFS, which messes up a good many permissions.
What I've done:
I've set up my project in /var/www/myproject/
Run chown -R me:www-data myproject
Run chmod -R 764 myproject
My new results:
Without nginx running:
uwsgi --http :8000 --module myproject.wsgi
works perfectly
With nginx running:
uwsgi --socket myproject.sock --module myproject.wsgi --chmod-socket=664
gives me a 502
uwsgi --ini myproject.ini
gives me a 502
So now it's not a general permission issue, it's definitely an issue with nginx...
Update #2:
For the moment, everything is working when other has read-write permissions on the socket, and read-execute permissions on the rest of the project.
So nginx is not recognized as it should... I've double-checked, and nginx is running as the www-data user, which is the group-owner of my entire project, and which has read-execute permissions, just as other now has.
Here's my (updated) nginx.conf
# myproject_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 unix:///var/www/myproject/myproject.sock;
# 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 my.ip.goes.here; # 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 /var/www/myproject/media; # your Django project's media files - amend as required
}
location /static {
alias /var/www/myproject/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 /var/www/myproject/uwsgi_params; # the uwsgi_params file you installed
}
}
And here's my (updated) uwsgi.ini
# myproject_uwsgi.ini file
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = /var/www/myproject
# Django's wsgi file
module = myproject.wsgi
# the virtualenv (full path)
home = /var/www/myenv
# process-related settings
master = true
# maximum number of worker processes
processes = 10
# the socket (full path)
socket = /var/www/myproject/myproject.sock
# ... with appropriate permissions - may be needed
chmod-socket = 666
uid = me
gid = www-data
# clear environment on exit
vacuum = true

From my experience, most of the permission problems around web server are by accessing file which is owned by root, but Apache (nginx) is running under www-data user.
Try running sudo chown www-data -R /path/to/your/data/folder.

As the tutorial said:
You may also have to add your user to nginx’s group (which is probably
www-data), or vice-versa, so that nginx can read and write to your
socket properly.
Try that and see what happens.
As well I wouldn't recommend you doing things with sudo or as root, do it as a normal user and place the permission as it get necessary, otherwise you might end up in a situation that Nginx or uWSGI need to do something with the files and they are owned by root.

Related

Django Download/Upload Files In Production

I have a Django project that is currently hosted. I am serving static files but do not know how to handle user file uploads / downloads in the MEDIA folder. I've read a lot about Docker, Nginx, and Gunicorn but have no idea which I need nor how to set them up. I've followed no less than 20 tutorials and watched no less than 15 YouTube videos but am still confused (I've visited every link for the first 2 pages of all my Google searches).
My question is, which of these do I need to allow users to upload/download files from a site? On top of that, I have tried getting all three working but can't figure them out, surely I'm not the only one that has so much difficulty with this, is there a good resource/tutorial which would guide me through the process (I've spent well over 40 hours reading about this stuff and trying to get it to work, I've gotten to the point where so long as it works, I don't care for understanding how it all fits together)?
Thank you.
edit - this is a stripped down version of what was requested. I haven't included the html as it's my first time doing this and I've used Ajax and things and it's a complete mess and I'm sure will just confuse you.
settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_files')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static_media')
STAT=os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [ STAT,
os.path.join('static/'),
os.path.join('templates/static/'), # for overridden templates css
]
view.py
class UploadView(View):
def get(self, request):
files_list = UploadedFile.objects.all()
return render(self.request, 'users/modules.html', {'files': files_list})
def post(self, request, *args, **kwargs):
data = {}
form = UploadedFileForm(self.request.POST, self.request.FILES)
form.instance.data_id = self.request.POST['data_id']
if form.is_valid():
uploaded_file = form.save()
Thank you.
So you want to know how to make your (working in development environment) project production-ready. Let's start with what components are required
Web Server (Nginx)
Application Server (uWSGI)
Application (Django)
Web Server serves the users' requests. It knows how to generate the correct output for a request - read a file from a filesystem, pass a request further to application server and so on. Nginx is the good choice.
Application Server is the middleman between Web Server and Application. It can spawn application instances (processes), balance the load between those instances, restart dead instances and many other things. uWSGI is good choice here.
Application - in your case it's Django project you have working in your development environment. You have everything ready here, but most likely you should adjust settings a bit. Django will communicate with Application Server through WSGI protocol.
At this point you should also understand how a web browser will load, render and display your site. All starts from a user who wants to open a page on your site, for example http://example.com/uploads. A browser will send HTTP GET request to your server and Web Server program (Nginx) will catch this request and decide what to do next.
Since that particular request isn't about some static file (static HTML file or static JPEG image and so on) - Nginx will decide to pass a request to Application Server. uWSGI will get the request and pass it forward to Django.
Django will use all the urls.py files to find the right view to generate the response for http://example.com/upload page. What your view will do?
def get(self, request):
files_list = UploadedFile.objects.all()
return render(self.request, 'users/modules.html', {'files': files_list})
it will return the HTML page (rendered template). So that HTML document will be returned back to Application Server, then back to Web Server and finally to a user's web browser.
Then a browser will start parsing of that HTML document and most likely it will find some additional resources to load - css, javascript, images, fonts, ... For each resource - it will make additional GET request to Web Server. And this time Web Server will not push requests forward to Application Server. It will just read those files from file system and return back to a browser.
Those resources are not dynamic, they are static. So you basically store them under static namespace. For example:
http://example.com/static/main.css
http://example.com/static/main.js
http://example.com/static/logo.png
...
Those files are the part of your application. Your application is shipped with those files. But also there're some files which could be uploaded to your system. You could save those files in any place - filesystem, database, ... But you must have URLs for them. Usually it's media namespace:
http://example.com/media/user-file.csv
http://example.com/media/reports/john-02-12-2020.pdf
...
In both cases - those calls will be just forwarded to Web Server and then to filesystem.
Why do you see everything working on your development environment? It's likely because you run the application with python manage.py runserver. In that case - Django is your Web Server as well (and there will be no Application Server middleman). So it will manage it's own instances, it will get user's requests, it will return static files, it will return "media" files, it will return dynamically generated pages and so on.
Each component described above needs it's own configuration file. Let me show you some examples you can use for your project.
Web Server (Nginx)
sites-enabled/default.conf
upstream uwsgi {
server uwsgi:8080;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
error_log /var/log/nginx/error.log;
charset utf-8;
location /media {
alias /home/web/media;
expires 7d;
}
location /static {
alias /home/web/static;
expires 7d;
}
location / {
uwsgi_pass uwsgi;
include uwsgi_params;
}
}
Notes:
everything under http://example.com/static will go to filesystem (/home/web/static directory)
for example: http://example.com/static/css/main.css -> /home/web/static/css/main.css
everything under http://example.com/media will go to filesystem (/home/web/media directory)
for example: http://example.com/media/reports/john-02-12-2020.pdf -> /home/web/media/reports/john-02-12-2020.pdf
everything else will be passed to uWSGI (to host uwsgi, to port 8080)
Application Server (uWSGI)
uwsgi.conf
[uwsgi]
req-logger = file:/var/log/uwsgi-requests.log
logger = file:/var/log/uwsgi-errors.log
workers = %k
# enable-threads = true
# threads = 4
chdir = /home/web/app
module = core.wsgi
master = true
pidfile=/tmp/app.pid
socket = 0.0.0.0:8080
env = DJANGO_SETTINGS_MODULE=core.settings
memory-report = true
harakiri = 60
listen = 10240
Notes:
chdir = /home/web/app - it's the path to your application
module = core.wsgi - your application should have directory with main (core) application called core (you should see wsgi.py there)
pidfile=/tmp/app.pid - just a place for pid file
socket = 0.0.0.0:8080 - it will listen port 8080
env = DJANGO_SETTINGS_MODULE=core.settings - again, you need main app to be called core (it should be inside core directory) and you should have settings.py inside it)
Docker / Docker Compose
You might need Docker and Docker Compose to orchestrate all that software. But it's possible to try run everything without it as well.
docker-compose.yml
version: "2.4"
services:
uwsgi:
build:
context: ./docker
dockerfile: Dockerfile
hostname: uwsgi
sysctls:
net.core.somaxconn: 10240
environment:
- DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE}
- C_FORCE_ROOT=${C_FORCE_ROOT}
volumes:
- ./config/uwsgi/uwsgi.conf:/uwsgi.conf
- ../app:/home/web/app
- ./static:/home/web/static:rw
- ./media:/home/web/media:rw
- ./logs:/var/log/
restart: always
networks:
myapp_backend:
aliases:
- uwsgi
web:
image: nginx
hostname: nginx
sysctls:
net.core.somaxconn: 10240
depends_on:
- uwsgi
volumes:
# - ./config/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./config/nginx/sites-enabled:/etc/nginx/conf.d
- ./media:/home/web/media:ro
- ./static:/home/web/static:ro
- ./logs:/var/log/nginx
ports:
- "80:80"
# - "443:443"
restart: always
networks:
- myapp_backend
networks:
myapp_backend:
Dockerfile
FROM python:3.9.0
RUN export DEBIAN_FRONTEND=noninteractive
ENV DEBIAN_FRONTEND noninteractive
RUN dpkg-divert --local --rename --add /sbin/initctl
RUN apt-get install -y --fix-missing && apt-get update -y
RUN apt-get install -y python3-pip \
python3-setuptools
COPY requirements.txt /requirements.txt
RUN pip install -r /requirements.txt
RUN pip install uwsgi
WORKDIR /home/web/app
EXPOSE 8080
CMD ["uwsgi", "--ini", "/uwsgi.conf"]
Directory Structure
You can use directory structure from this repository: https://github.com/ansysy24/GameEconomy/tree/master/deployment
Also I highly recommend this article https://andrey-borzenko.medium.com/simple-nginx-uwsgi-daphne-reactive-application-part-1-the-big-picture-20d7b9ee5b96
And don't forget to add .env file like this one https://github.com/ansysy24/GameEconomy/blob/master/deployment/.env_template (but you should rename ofc)

Django Deployment with nginx - gunicorn from another server

I'm trying to deploy my Django Project through different application server : Apache2, Nginx/gunicorn, ...
It works fine with Apache2 or Nginx, but I would like to dissociate these application server with my Django Projet. I would like to get an environment like this :
Server 1 (172.30.10.92) : Django Project & wsgi
Server 2 (172.30.10.93) : Nginx/gunicorn
Why ? Because later I will have some Django applications, but I would like to use just one application server.
I think I'm making a mistake with my configuration files syntax.
I have in /etc/nginx/sites-available/DatasystemsCORE.conf :
server {
listen 8000;
server_name 172.30.10.92;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root http://172.30.10.92:/var/www/html/;
}
location / {
include proxy_params;
proxy_pass http://172.30.10.92/unix:/var/www/html/DatasystemsCORE/dscore.sock;
}
}
server_name : Is it IP adress from Django server or nginx server ? I think it's the first one but I'm not sure.
proxy_pass : I think there is an issue in my path
Then, I'm executing this command :
gunicorn --daemon --workers 3 --bind 172.30.10.92/unix:/var/www/html/DatasystemsCORE/dscore.sock 172.30.10.92:/var/www/html/DatasystemsCORE/DatasystemsCORE.wsgi
One more time, I thing there is a syntax problem because I'm getting 502 Bad Request
How I can add IP address from a distant Django server there ?
Thank you !
I found How to solve my issue and I made a tutorial (based on my case) in order to help everyone who would like to make the same thing.
My file is there : Download tutorial file
But this is the same tutorial written in English.
My Django IP server : 172.30.10.92
My Nginx IP server : 172.30.10.93
1- Install and Configure wsgi (located on Django server)
WSGI is a file created with your Django project.
The file is located in /path/to/your/project/Myproject/wsgi.py
We have to edit this file like this :
import os
from django.core.wsgi import get_wsgi_application
import sys sys.path.append('/var/www/html/Myproject')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Myproject.settings")
application = get_wsgi_application()
2- Install and Configure gunicorn/supervisor (located on Django server)
In order to install gunicorn/supervisor, you have to execute in your shell :
pip install gunicorn
pip install supervisor
Then, you have to create a new file in /etc/supervisor/conf.d/Myproject.conf which looks like this :
[program:Myproject]
command = /home/valentin/.virtualenvs/MyprojectEnv/bin/gunicorn Myproject.wsgi:application --name "Myproject" --workers=4 --bind=0.0.0.0:8080 -- user="valentin" --group="valentin" ; Command to start app
user = username #You have to replace by your username
stdout_logfile = /var/log/supervisor/supervisor.log
redirect_stderr = true
log
environment=LANG=fr_FR.UTF-8,LC_ALL=fr_FR.UTF-8
I specified port 8080 which is the communication port between my application server and my web server.
3- Edit hosts file on nginx server (located on nginx server)
You have to edit your hosts file located to /etc/hosts and add a new entry to your Django server :
127.0.0.1 localhost
127.0.1.1 valentin
172.30.10.92 Myproject
# The following lines are desirable for IPv6 capable hosts ::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
4- New config file in nginx repository (located on nginx server)
This new file should be placed in /etc/nginx/sites-available/Myproject.conf
server {
listen 8080;
server_name Myproject;
root /var/www/html/Myproject/;
location /static/ {
root /var/www/html/;
}
location / {
include proxy_params;
proxy_pass http://172.30.10.92:8080;
}
}
The IP address corresponds to my Django server address. I specified the listen port (8080), the path to my Django project & static directory.
Then, you have to create a symbolic link to sites-enabled.
After ths operation, restart nginx service :
sudo service nginx restart
5- Allow nginx IP address in Django (located on Django server)
You have to edit your settings.py file in order to allow nginx IP address in ALLOWED_HOSTS :
ALLOWED_HOSTS = ['localhost', '172.30.10.93', '127.0.0.1', '[::1]']
6- Finally execute gunicorn (located on Django server)
Finally, you have to start gunicorn. You should be inside your Django root project and execute :
gunicorn Myproject.wsgi:application --bind 172.30.10.92:8080
Now, in your browser, try to connect to your nginx server with the port :
http://172.30.10.93:8080
It works !
PS : This tutorial works for me, if it doesn't work for you, maybe I missed something, or maybe you didn't make exactly like me ;)
What you're trying to do doesn't make any sense. You can certainly use a single nginx on a separate server, but gunicorn is the application server and belongs with the application.
There is no "Django server" so your first question is irrelevant. gunicorn will need to serve on a port, not a socket, and the nginx proxy_pass will point to that port.

my nginx cannot load uwsgi on Ubuntu 16.04

trying to run django app "mysite" through uwsgi with nginx on Ubuntu 16.04, but when I start uwsgi and check in my browser, it just hangs.
i set django upstream socket to on port 8002 and nginx to listen on 8003. In the browser i visit 192.168.0.17:8003 prior to running uwsgi and it throws 502 which is expected, so I start uwsgi with
uwsgi --http :8002 --module mysite.wsgi --logto /tmp/uwsgi.log --master
and 8003 now hangs when I reload in the browser. I looked through /var/log/nginx/error.log but it's blank (so is access.log).
Here is nginx config, which is symlinked to /etc/nginx/sites-enabled:
sudo nano /etc/nginx/sites-available/mysite_nginx.conf
# 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:8002; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 8003;
# the domain name it will serve for
server_name 192.168.0.17; # 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/myusername/uwsgi-tutorial/mysite/media; # your Django project's media files - amend as required
}
location /static {
alias /home/myusername/uwsgi-tutorial/mysite/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/myusername/uwsgi-tutorial/mysite/uwsgi_params; # the uwsgi_params file you installed
}
}
I know that Django is running because in my app's settings.py I have ALLOWED_HOSTS = ['192.168.0.17','localhost','127.0.0.1'] and when I visit port 8002 in the browser I get the django "Congratulations!" page. And when I remove 192.168.0.17 from ALLOWED_HOSTS, django still runs on that machine from localhost or 127.0.0.1, so this seems that it must be something to do with how ngnix and uwsgi are talking to each other.
Any ideas??
It turns out systemd does not like lines in config files to be too long. I removed a couple long comments in /etc/systemd/system/uwsgi.service, restarted uwgsi service and all is well.
I found this out by running sudo journalctl -u uwsgi and finding the following error:
[/etc/systemd/system/uwsgi.service:5] Unbalanced quoting, ignoring: "/bin/bash -c 'mkdir -p /run/uwsgi; chown myusername:myusern
In researching Unbalanced quoting, found this git issue regarding maximum file line length.

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

Django + uwsgi + nginx redirect to default page "Welcome to NGINX"

I'm a very beginner in python and django. However I'm trying to create a server to deploy my application. But when I want to access my app, I always get the default nginx page "Welcome to nginx".
This server is on Ubuntu 12.04 (precise)
I've installed nginx, python, django and uwsgi packages with apt.
Next I've created a django project to /var/www/djangoApps and a django app to /var/www/djangoApps/testApp
This is my /etc/nginx/sites-available/djangoApps :
server {
listen 80
server_name django.pommesky.com;
rewrite ^(.*) http://www.django.pommesky.com/$1 permanent;
}
server {
listen 80;
server_name www.django.pommesky.com;
access_log /var/log/nginx/djangoApps_access.log;
error_log /var/log/nginx/djangoApps_error.log;
location /media {
alias /var/www/djangoApps/media/;
}
location /static {
alias /var/www/djangoApps/static/;
}
location / {
uwsgi_pass unix:///run/uwsgi/app/djangoApps/socket;
include uwsgi_params;
}
}
And this is my /etc/uwsgi/apps-available/djangoApps.ini :
env = DJANGO_SETTINGS_MODULE=djangoApps.settings
module = django.core.handlers.wsgi:WSGIHandler()
chdir = /var/www/djangoApps
socket = /run/uwsgi/djangoApps/socket
logto = /var/log/uwsgi/djangoApps.log
The uwsgi log doesn't show anything, everything seems to run well, it finishes by spawned uWSGI worker ...
But /var/log/nginx/djangoApps_access.log; and /var/log/nginx/djangoApps_error.log; don't exist, which is very strange.
I can't figure out what's wrong with my configuration.
Please help me ...
The domain django.pommesky.com doesn't look like it's alive, so it's possible that Nginx is receiving requests with wrong Host: field in the HTTP request header. (sect. 14.23) So Nginx serves a default catch-all page.
You can disable the default Nginx site by removing the /etc/nginx/sites-enabled/default link, and then restarting the daemon.
sudo rm -v /etc/nginx/sites-enabled/default
sudo service nginx restart
You can reenable by recreating the link:
sudo ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
sudo service nginx restart
The other thing you can try is to setup Bind or another DNS daemon to serve a fake pommesky.com zone with all the subdomains you want and use that DNS while you're developing your site.
Of course you can also register that domain with a hosting provider, and then use the DNS zone editor in its control panel to setup your subdomains and all the PTRs you want to whatever public IP addresses you need.