我正在开发一个django API,它将通过WSGI在运行Ubuntu的服务器上运行于Apache 2之上。
用户可以使用POST请求将他们拍摄的图片上传到服务器。API处理此请求,然后尝试将图像写入/var/www/media/animals/user_uploads/<animal_type>/<picture_name>.jpg
。如果没有目录/var/www/media/animals/user_uploads/<animal_type>/
,它将创建一个目录。
在开发过程中进行测试时,使用Windows和Scientific Linux时一切正常。在部署服务器上进行测试时,收到以下错误:
据我所知,Apache 2服务器正在使用用户www-data
运行。在我的示例中,运行cat /etc/passwd
以获得用户列表,这是www-data
的结果:
网站数据:x:33:33:网站数据:/var/网站数据:/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/
6条答案
按热度按时间vtwuwzda1#
最后我自己解决了这个问题。
当在开发机器上运行时,我实际上是在使用我当前用户的权限运行。然而,当在部署服务器上运行时,我实际上是通过
wsgi
运行的,这意味着它是使用www-data
的权限运行的。www-data
既不是所有者,也不在拥有/var/www
的用户组中。这意味着www-data
被视为other
,并将权限设置为其他用户。坏解决方案是:
这将使每个人都可以完全访问
/var/www/
,which is a very bad idea中的所有内容。另一个糟糕的解决方案是:
这会将所有者更改为
www-data
,which opens security vulnerabilities。好的解决方案是:
这会将
www-data
添加到varwwwusers
组,然后将其设置为/var/www/
及其所有子文件夹的组。您可以将其设置为750
以使其更安全,但这样您将无法使用Django's
collectstatic
功能,因此请坚持使用770
,除非您对自己的操作非常有信心。krugob8w2#
在项目的根目录中创建一个“MEDIA”目录。然后设置:
fnatzsnv3#
要了解您登录到的用户,请执行以下操作:
如果您正在使用AWS示例,则应将您的用户添加到能够访问该文件夹的组中:
为Web服务用户(varwwwusers)创建组
更改www文件夹并使其属于varwwwusers
www-data是发出django请求的服务器,将其添加到组中
更改文件夹策略
将ubuntu添加到varwwwusers组
希望这对你有帮助!
jucafojl4#
在处理生产服务器时,此问题的解决方案是使用collectstatic(如前所述),它使用并解析或给予文件夹权限。但是,如果您的解决方案位于本地环境中,则可以通过在本地服务器上的
settings.py
文件中配置本地MEDIA
目录来获取解决方案。因此,将在本地配置文件中添加这两行,如@Nic Scozzaro所述:
配置完成后,重新启动服务以应用修复程序。
rbpvctlc5#
而不是:
MEDIA_ROOT = os.path.join(BASE_DIR, '\media\')
增加以下内容:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
v9tzhpje6#
不像其他人,这是我的答案(ubantu与gunicorn nginx)
而不是:
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
增加以下内容:
MEDIA_ROOT = os.path.join(BASE_DIR, '/media/')