Django [Errno 13] 权限被拒绝:'/var/www/media/animals/user_uploads'
Posted
技术标签:
【中文标题】Django [Errno 13] 权限被拒绝:\'/var/www/media/animals/user_uploads\'【英文标题】:Django [Errno 13] Permission denied: '/var/www/media/animals/user_uploads'Django [Errno 13] 权限被拒绝:'/var/www/media/animals/user_uploads' 【发布时间】:2014-03-14 21:03:25 【问题描述】:我正在开发一个 django API,它将在运行 Ubuntu 的服务器上通过 WSGI 在 Apache2 之上运行。
用户将能够使用 POST 请求将他们拍摄的照片上传到服务器。 API 处理此请求,然后尝试将图像写入/var/www/media/animals/user_uploads/<animal_type>/<picture_name>.jpg
。如果没有目录/var/www/media/animals/user_uploads/<animal_type>/
,它将创建它。
在开发期间进行测试时,一切都很好,无论是使用 Windows 还是 Scientific Linux。在部署服务器上测试时,我收到此错误:
据我了解,Apache2 服务器正在使用用户 www-data
运行。就我而言,运行cat /etc/passwd
来获取用户列表,这就是我为www-data
得到的:
www-data:x:33:33:www-data:/var/www:/bin/sh
我假设这意味着www-data
可以访问/var/www/
中的所有内容。我试过了:
chmod 777 -R 媒体
这行得通,但显然是解决这个问题的一个非常糟糕的方法。有没有更好的方法来解决这个问题?
这是我的 wsgi.py:
import os, sys
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "serengeti.settings")
sys.path.append('/serengeti/django/serengeti')
sys.path.append('/serengeti/django')
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
我的settings.py
文件中有这个:
MEDIA_ROOT = '/var/www/media/'
MEDIA_URL = os.path.join(BASE_DIR,'/media/')
我的vhost.conf
包含以下内容:
Alias /media/ /var/www/media/
【问题讨论】:
【参考方案1】:在项目的根目录中创建一个“MEDIA”目录。 然后设置:
MEDIA_ROOT = os.path.join(BASE_DIR,'MEDIA')
【讨论】:
【参考方案2】:与其他人不同,这是我的答案(ubantu 与 gunicorn nginx)
而不是:MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
添加以下内容:MEDIA_ROOT = os.path.join(BASE_DIR, '/media/')
【讨论】:
这没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review【参考方案3】:而不是:
MEDIA_ROOT = os.path.join(BASE_DIR, '\media\')
添加以下内容:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
【讨论】:
【参考方案4】:在处理生产服务器时,解决此问题的方法是使用前面提到的 collectstatic,它使用并解决或授予文件夹权限。但是,如果您的解决方案是在本地环境中,则可以通过在作用于本地服务器的settings.py
文件中配置本地MEDIA
目录来获取解决方案。
所以,就像@Nic Scozzaro 提到的那样,在本地配置文件中添加这两行:
MEDIA_ROOT = os.path.join (BASE_DIR, 'media')
STATIC_ROOT = os.path.join (BASE_DIR, 'static')
配置后重新启动服务以应用修复。
【讨论】:
【参考方案5】:最后我自己解决了这个问题。
在开发机器上运行时,我实际上是在使用当前用户的权限运行。但是,在部署服务器上运行时,我实际上是通过wsgi
运行的,也就是说它是使用www-data
的权限运行的。
www-data
既不是所有者,也不是拥有/var/www
的用户组。这意味着www-data
被视为other
并具有设置给其他人的权限。
BAD 解决方案是:
sudo chmod -R 777 /var/www/
这将使每个人都可以完全访问/var/www/
、which is a very bad idea 中的所有内容。
另一个不好的解决方案是:
sudo chown -R www-data /var/www/
这会将所有者更改为www-data
、which opens security vulnerabilities。
GOOD 解决方案是:
sudo groupadd varwwwusers
sudo adduser www-data varwwwusers
sudo chgrp -R varwwwusers /var/www/
sudo chmod -R 760 /var/www/
这会将www-data
添加到varwwwusers
组,然后将其设置为/var/www/
及其所有子文件夹的组。 chmod
将授予所有者读取、写入、执行权限,但如果网络服务器被黑客入侵,该组将无法执行可能上传的任何脚本。
您可以将其设置为740
以使其更安全,但您将无法使用Django's
collectstatic
功能,因此请坚持使用760
,除非您对自己的身份非常有信心做。
【讨论】:
我如何知道我需要添加哪个用户? 我不明白为什么“GOOD”解决方案比sudo chown -R www-data /var/www/ option
更安全。在这两个选项中,您都授予 Web 服务器用户 (www-data) rwx 对整个目录的访问权限。一个给组 rwx,另一个用 rwx 指定所有者。如何更安全地使用群组?
@rsynnest 好点。我的意思是将它设置为 760,以避免在服务器以某种方式被黑客入侵并且在那里上传了一些脚本时允许执行。我已经更新了它。有关详细信息,请参阅此:security.stackexchange.com/a/65201/20064
对目录的权限6
使其无法访问。 www-data 将无法通过 760
权限从 /var/www 遍历或读取任何内容。如果您希望目录可访问,则必须为目录提供一个奇怪的八进制权限。
我相信你的链接的赞成票,他们都谈到了目录的有效权限,750 或 770。人们肯定跟着他们并相应地纠正了他们,因此这个小错误被忽略了。【参考方案6】:
要知道您登录的是哪个用户:
$ whoami
ubuntu
添加到您的解决方案中,如果您使用的是 AWS 实例,您应该将您的用户添加到组中以便能够访问该文件夹:
为 Web 服务用户 (varwwwusers) 创建一个组
$ sudo groupadd varwwwusers
更改 www 文件夹并使其属于 varwwwusers
$ sudo chgrp -R varwwwusers /var/www/
www-data 是发出 django 请求的服务器,将其添加到组中
$ sudo adduser www-data varwwwusers
更改文件夹策略
$ sudo chmod -R 770 /var/www/
将 ubuntu 添加到 varwwwusers 组
$ usermod -a -G varwwwusers ubuntu
希望这会有所帮助!
【讨论】:
不应该是sudo usermod -a -G varwwwusers ubuntu
吗?
我仍然面临权限被拒绝错误。我相信这可能是由于 apache 配置。你也可以分享那个文件吗?另外请分享设置conf以确保。谢谢!以上是关于Django [Errno 13] 权限被拒绝:'/var/www/media/animals/user_uploads'的主要内容,如果未能解决你的问题,请参考以下文章
Django [Errno 13] 权限被拒绝:'/var/www/media/animals/user_uploads'
如何修复以下 Django 错误:“类型:IOError”“值:[Errno 13] 权限被拒绝”
ValueError:无法配置处理程序“文件”:[Errno 13] 权限被拒绝:
apache配置中的权限被拒绝:[Errno 13]权限被拒绝