2

I'm trying to set up a Django app using uwsgi and nginx, but I keep butting my head against a very irritating problem.
I've used the uwsgi docs as a reference guide.

When serving the app through uwsgi (uwsgi --http :8000 --module myproject.wsgi) everything works fine, but when I try to connect through a socket with nginx (uwsgi --ini myproject.ini) and open myproject.com:8000/<django-app> in my browser I get a 502 error and

2018/02/07 08:25:26 [crit] 30339#30339: *1 connect() to unix:///var/www/[myproject]/[myproject].sock failed (13: Permission denied) while connecting to upstream, client: [client-ip], server: [server-ip], request: "GET /[django-app]/ HTTP/1.1", upstream: "unix:///var/www/[myproject]/[myproject].sock:", host: "[fqdn]:8000"

this ^ in /var/log/nginx/error.log

My project folder is under /var/www/, owned by <me>:www-data, and with 764 as permissions. Every subfolder and file is (currently) under this ownership and these permissions.

I'm running everything on a Ubuntu 16.04 virtual machine (managed by my admin), and my user has sudo access.


Am I missing something obvious?


Update:
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.


myproject_nginx.conf
(In addition to the settings in this file, I've put user www-data www-data; in /etc/nginx/nginx.conf.)

# myproject_nginx.conf

# the upstream component nginx needs to connect to
upstream django {
    server unix:///var/www/myproject/myproject.sock;
}

# 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
    }
}

myproject_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
DoTheGenes
  • 21
  • 1
  • 1
  • 6

4 Answers4

2

After a few hours of pain I found a solution to this exact issue.

The problems are two: 1) the folder's permissions 2) the virtual environment

The virtual environment messes with your permissions and prevents uwsgi from creating the socket correctly - just deactivate the venv and pip install django and uwsgi system wide. There may be a way to solve this within the venv, but I don't know of any.

Then, set your django project folder's permissions to 777 (or change its owner to root).

cd into the folder and run the wsgi command as root:

sudo uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=664 --uid www-data --gid www-data

this creates mysite.sock with owner www-data and I no longer get the permission denied error.

I hope this helps.

-edit- after some more investigation, I followed this tutorial and got it working as a systemd service without any of these issues - I guess the official tutorial takes some things for granted.

0

I always start out when doing deployment development and/or testing by running something like this:

uwsgi --socket /tmp/mysite.sock --module mysite.wsgi --chmod-socket=777

Then once you see your site working, you can work towards using the INI file method. This is nice because the command to start your app server is simplified to:

uwsgi --ini mysite.ini

Giorgio Ghisotti already mentioned all this so that answer should be accepted.

nicorellius
  • 585
  • 2
  • 5
  • 23
0

In this tutorial for Using Unix sockets instead of ports, this command worked:

uwsgi --socket mysite_nginx.sock --wsgi-file test.py --chmod-socket=666
Andrew Schulman
  • 8,811
  • 21
  • 32
  • 47
0

I hit a similar problem based on a similar digital ocean tutorial.

https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uwsgi-and-nginx-on-ubuntu-16-04#

My hack was to chmod a+rw mysite.sock after starting uwsgi.

However, I imagine changing --chmod-socket=666 would also work.

  • The socket file is created and destroyed each time you run uwsgi so changing perms manually is not a sustainable solution. – nicorellius Feb 18 '21 at 19:33