Django在Ubuntu服务器写入媒体文件时遭遇Errno 13权限拒绝及当前工作目录异常的问题咨询
问题根源拆解
1. 为什么工作目录变成了/?
你在本地用python manage.py runserver启动Django时,开发服务器会继承你终端的工作目录(也就是项目根目录)。但在Ubuntu上,Django通过Apache的WSGI模块运行时,Apache的默认工作目录就是系统根目录/,所以models.py里的os.getcwd()返回/完全正常——这也是依赖相对路径会出问题的核心原因。
2. 权限拒绝的本质原因
从你贴的进程信息能看到,Apache的子进程是用www-data用户跑的,但你的media文件夹属于admin用户组。虽然文件夹权限是drwxrwxr-x(组用户有读写权限),但www-data不在admin组里,自然没有写入权限。而你在shell里测试时用的是admin用户,所以能正常写入,这就是环境差异。
分步解决办法
第一步:彻底修复路径问题(别再依赖工作目录)
绝对不要用相对路径或者os.getcwd()来拼文件路径,直接用Django配置好的MEDIA_ROOT生成绝对路径,这样不管进程在哪跑都不会错。修改你的template_to_file方法:
from django.conf import settings import os def template_to_file(self): # 用MEDIA_ROOT构建可靠的绝对路径 file_path = os.path.join(settings.MEDIA_ROOT, 'newsletter-volume-1.html') with open(file_path, 'w') as static_file: static_file.write('Hello')
第二步:给Apache进程赋予Media文件夹写入权限
有两种常用方案,选一种就行:
方案A:把www-data加入admin用户组
sudo usermod -aG admin www-data
然后重启Apache生效:
sudo systemctl restart apache2
这样www-data就拥有了admin组的读写权限,匹配你media文件夹的drwxrwxr-x权限设置。
方案B:直接修改Media文件夹的所有者
如果你不想让www-data加入admin组,直接把media文件夹的所有者改成www-data:
sudo chown -R www-data:www-data /home/admin/backoffice/media
同样要重启Apache服务。
第三步:Celery进程的权限注意(可选)
看到你还跑了Celery Beat进程,它是以admin用户运行的。如果后续Celery也需要写入media文件夹,它本身权限是够的,但如果路径问题没修复,同样会出问题——所以第一步的路径修复是通用的。
本地OSX正常的原因
本地用runserver时,进程是你的用户(tb),和media文件夹的所有者一致,所以权限没问题;同时runserver的工作目录就是项目根目录,相对路径能正常找到media文件夹,自然一切正常。
内容的提问来源于stack exchange,提问作者Radial

