Nginx+uWsgi+Django遇到'Permission denied while connecting to upstream' (socket)错误

8

我在 Stack Overflow 上看到很多与这个主题相关的问题,尝试了尽可能多的方法,但仍然无法解决我的问题,所以我希望这篇文章可能会有所帮助。

我正在按照这个网站上的教程,在 Nginx 中使用 uWSGI 设置 Django:http://www.oliverelliott.org/article/computing/tut_setup_nginx_django/

uwsgi.ini 文件

[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;
    }
}

这是在/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"

请注意:CLIENT_IP和HOST_IP是ip地址值。
这些是我尝试过但没有成功的方法: 1. 对主目录运行"chmod 755",然后运行"uwsgi --socket awssite.socket --module awssite.wsgi --chmod-socket=666" 2. 将用户nginx添加到我的用户组中,然后运行"uwsgi --socket awssite.socket --module awssite.wsgi --chmod-socket=664" 3. 通过添加以下新行更改ini文件: chown-socket=ec2-user:nginx uid=nginx gid=nginx 然后运行"uwsgi --ini uwsgi.ini"。这会返回“chown权限被拒绝”,但当我使用"sudo"命令运行该命令时,我得到"sudo: uwsgi: command not found"(uWSGI已在系统范围内安装)。 4. 将所有文件放在不同的目录中(超出用户ec2-user),但这不允许我访问它们,除非我以root身份运行,即使这样也无法工作。 5. 运行"uwsgi --socket awssite.socket --module awssite.wsgi --chmod-socket=664/666",带有参数"--uid nginx"、"--gid nginx"、"--chown-socket=nginx:nginx"。请注意:"664/666"表示我尝试了两种权限。 6. 重命名nginx.conf.default和nginx.conf.rpmnew文件(使nginx要读取的唯一conf文件为"nginx.conf")。
请问有人能够解决我的问题吗?我会在这个问题上继续添加我尝试过但没有成功的方法。谢谢 :)
编辑:感谢@GwynBleidD的答案,我终于让它工作了。 以下是有效的方法: 将套接字文件保留在"/tmp"中 etc/nginx/sites-enabled/awssite_nginx.conf
upstream django {
    server unix:///tmp/djangosocket/awssite.socket;
}
....

uwsgi.ini 文件

[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

我将我的 ec2-user (当前登录用户)加入到组 nginx 中。
然后相应地更改了文件权限:
chown -R ec2-user:nginx djangosocket
chmod g+rwx djangosocket


你可以尝试将chdir更改为chdir=/home/ec2-user/project吗? - Selcuk
@Selcuk,不行,那个方法没用。据我理解,chdir是项目中应用的路径,而不是项目本身的路径。 - carol Alex
我总是切换到项目目录,但不包括home参数。 - Selcuk
我明白了,我尝试过使用chdir切换到项目目录并删除home参数,但是当uwsgi读取我的模块参数时会出现错误;我不认为这是我的问题的解决方案。你有其他我可以尝试的选项吗?@Selcuk - carol Alex
抱歉,我刚才才意识到你的项目名称是 awssite。不好意思,我没有任何建议,因为你的配置看起来很正常。 - Selcuk
1个回答

11
如果您的nginx服务器无法访问uWSGI套接字,请尝试执行以下步骤:
  1. 不要将套接字放在系统中任何用户的主目录中,特别是root!某些Unix操作系统默认会阻止除该目录所有者和root之外的任何人访问主目录。将nginx用户添加到该用户的私有组中(对于大多数系统,每个用户都有自己的主组)可能有所帮助,但这几乎永远不会对root起作用。

  2. 检查nginx服务器(或任何其他正在使用的http服务器)运行的用户和组。有时是www-data,有时是nginx,有时是其他东西。创建套接字时,请确保用户名与运行uWSGI服务器的用户名匹配,并且组名与uWSGI运行的组匹配(或者您可以互换它们)。

  3. 检查您的套接字权限至少为660。没有必要将其授予任何人的权限,因此不要这样做。

  4. 检查您的nginx和uWSGI是否有权限访问放置套接字的目录以及所有父目录。

套接字文件的好位置是/var/run目录(对于某些系统,它是/run或两者都是)。它最常作为ramdisk(tmpfs)挂载,并且任何系统中的用户都可以在此处创建套接字(并访问它们)。如果在您的系统中由于某种原因无法访问它,请尝试/tmp目录。

如果您还从自己的主目录直接提供静态文件,则考虑将nginx添加到个人组中,以便它可以读取您的主目录和静态文件。


成功了!/var/run目录不幸没有写入权限,但将套接字放在/tmp中可以工作。我还必须将用户nginx添加到我的用户组ec2-user中,以便它可以访问套接字所在的目录。一个快速的问题:有没有办法让这个工作,而不必让nginx在我的用户组ec2-user中?(这样nginx就不会访问ec2-user拥有访问权限的所有其他文件和目录) - carol Alex
1
是的,但是您必须更改目录和套接字文件的所有者,以使用户或组与nginx匹配。 - GwynBleidD
我已将ec2-user用户添加到nginx组中。并且我运行了chown -R nginx:nginx /tmp/testfolder命令,并在我的uwsgi.ini文件中添加了这一行sudo chown-socket=nginx:nginx。但是,当我尝试运行uwsgi --ini uwsgi.ini时,我遇到了以下错误:error removing unix socket, unlink(): Permission denied [core/socket.c line 198] bind(): Permission denied [core/socket.c line 230]。你有什么想法吗? - carol Alex
好的,我解决了!只有用户(nginx)对/tmp/testfolder有读写执行权限,所以我修复了这个问题,现在它可以正常工作了!它可以在不必更改套接字文件的所有者的情况下运行,我对此非常高兴。我会编辑我的答案,并提供更新后的uwsgi.ini文件,让其他人看看现在是如何工作的。非常感谢! - carol Alex
为了确保其安全性,您应该将该文件夹的用户或组分配给您的用户,并将chmod更改为770。 - GwynBleidD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接