Nginx+uWsgi+Django 'Permission denied while connecting to upstream' (socket)
Asked Answered
S

1

8

I've seen alot of questions on SO regarding this topic and I've tried out as many methods as I could but it still isn't solving the issue for me so I'm hoping this post might be helpful.

I'm following the tutorial from this site to set up Django on Nginx wtih uWSGI: http://www.oliverelliott.org/article/computing/tut_setup_nginx_django/

uwsgi.ini file

[uwsgi]
chdir=/home/ec2-user/project/awssite
module=awssite.wsgi
home=/home/ec2-user/project
master=true
processes=2
socket=/home/ec2-user/project/awssite/awssite.socket
chmod-socket=666
vacuum=true

etc/nginx/sites-enabled/awssite_nginx.conf

upstream django {
    server unix:///home/ec2-user/project/awssite/awssite.socket;
}
server {
listen          8080;
    server_name     localhost;
    charset utf-8;

    #max upload size
    client_max_body_size 75M;

    #Django media
    location /media {
            alias /home/ec2-user/project/awssite/awssite/media;
    }

    location /static {
            alias /home/ec2-user/project/awssite/awssite/static; 
    }

    location /favicon.ico {
            log_not_found off;
    }

    location / {
            uwsgi_pass django;
            include /home/ec2-user/project/awssite/uwsgi_params;
    }
}

This is the error code in /var/log/nginx/error.log

2016/02/15 01:21:22 [crit] 22159#0: *3 connect() to unix:///home/ec2-user/project/awssite/awssite.socket failed (13: Permission denied) while connecting to upstream, client: CLIENT_IP, server: localhost, request: "GET /menu/ HTTP/1.1", upstream: "uwsgi://unix:///home/ec2-user/project/awssite/awssite.socket:", host: "HOST_IP:8080"

Note: CLIENT_IP & HOST_IP are ip address values.

These are what I have tried and not worked:
1. chmod 755 home directory and running uwsgi --socket awssite.socket --module awssite.wsgi --chmod-socket=666

2. Adding user nginx to my user group and running uwsgi --socket awssite.socket --module awssite.wsgi --chmod-socket=664

3. change ini file by adding these new lines
chown-socket=ec2-user:nginx uid=nginx gid=nginx and then running uwsgi --ini uwsgi.ini This returns with 'Permission denied for chown' but when I run the command with sudo, i get sudo: uwsgi: command not found (uWSGI is installed system-wide)

4. Put all the files in a different directory (outside of user ec2-user) but that does not allow me to access them unless I run as root and even then it does not work

5. running uwsgi --socket awssite.socket --module awssite.wsgi --chmod-socket=664/666 with parameters --uid nginx --gid nginx --chown-socket=nginx:nginx Note: 664/666 meaning I tried both permissions

6. Renamed nginx.conf.default and nginx.conf.rpmnew files (so that the only conf file for nginx to read off is nginx.conf)

Could someone please shed some light on how I may resolve this issue? I will continue to add on methods that I've tried and not worked on this question while I work on it. Thanks :)

EDIT: Thanks to @GwynBleidD answer, I finally got it working. This is what works:

kept my socket file in /tmp
etc/nginx/sites-enabled/awssite_nginx.conf

upstream django {
    server unix:///tmp/djangosocket/awssite.socket;
}
....

uwsgi.ini file

[uwsgi]
chdir=/home/ec2-user/project/awssite
module=awssite.wsgi
home=/home/ec2-user/project
master=true
processes=2
socket=/tmp/djangosocket/awssite.socket
chmod-socket=666
vacuum=true

I added my ec2-user (logged in user) to group nginx.
I changed the file permissions accordingly
chown -R ec2-user:nginx djangosocket
chmod g+rwx djangosocket

Snowblink answered 15/2, 2016 at 1:57 Comment(5)
Can you try changing your chdir to chdir=/home/ec2-user/project?Croatian
@Croatian nope that didn't work. to my understanding, chdir is the path to the app in the project not the project itself.Snowblink
I always chdir to the project dir but I don't include the home argument.Croatian
I see, I tried chdir to the project dir and removed the home argument but that gives me errors when uwsgi reads my module argument; don't think that would be a solution for my question. Do you have any other options I can try? @CroatianSnowblink
Sorry, just realized that your project name is awssite. No, I don't have any suggestions as your config seems ok to me.Croatian
R
11

If your nginx server can't access uWSGI socket, try to fulfill following steps:

  1. don't put your socked in home directory of any user in your system, especially root! Some of unix operating systems are blocking by default access to home directory for anyone except owner of that directory and root. Adding nginx user to private group of that user (for most of systems, each user has it's own, main group) can help with that, but it will almost never work for root.

  2. check on what user and group your nginx server (or any other http server that you're using) runs. Sometimes is www-data, sometimes nginx, sometimes something other. When creating socket, make sure that username will match username on which uWSGI server runs and group name match group on uWSGI runs (or you can swap it).

  3. Check that your socket's permissions are at least 660. There is no need to give permissions to it for anyone, so don't do that.

  4. Check that both your nginx and uWSGI have permission to access directory on which socket is put, and all parent directories.

Good place for your socket's file is /var/run directory (for some systems it is /run or both). It is most often mounted as ramdisk (tmpfs) and it is write'able for anyone in system, so every user can create sockets here (and access them). If it's for some reason not accessible in your system, you can also try /tmp directory.

If you're also serving static files directly from nginx from your home directory, consider adding nginx to your personal group, so it will have read access to your home directory and static files.

Recovery answered 15/2, 2016 at 9:35 Comment(5)
It works! /var/run directory was unfortunately not giving write access but putting the socket in /tmp worked. I also had to add user nginx to my usergroup ec2-user so it could access the directory the socket is put. Quick question: is there a way i can get this to work without having nginx in my usergroup ec2-user? (just so nginx won't have access to all other files and directories that ec2-user has access to)Snowblink
Yes, but you must chown directories and socket file, so either user or group will match nginx one.Recovery
i've added ec2-user user in nginx group. and i've run chown -R nginx:nginx /tmp/testfolder and i've added this line in my uwsgi.ini file sudo chown-socket=nginx:nginx. this is the error i'm getting. ` error removing unix socket, unlink(): Permission denied [core/socket.c line 198] bind(): Permission denied [core/socket.c line 230] ` (i'm getting this when i try to run uwsgi --ini uwsgi.ini) any ideas?Snowblink
ok figured it! only the user (nginx) had rwx access to /tmp/testfolder so i fixed that up and it works!. it worked without me having to chown the socket file so i'm pretty happy about that. i'll edit my answer with an updated uwsgi.ini file for anyone else to have a look at what works now. Thanks so much!Snowblink
For proper security of it, you should leave user or group of that folder assigned to your user and change chmod to 770Recovery

© 2022 - 2024 — McMap. All rights reserved.