在新生产服务器上上传文件时出现 PermissionError

PermissionError when uploading file on new production server

我将 Django 项目迁移到新的生产服务器。在以前的生产服务器上,一切正常。迁移时,我升级到 Ubuntu 20.04 和 Django 4.0.3。现在一切都恢复正常了,除了上传文件。

当我尝试创建 Invoice 对象的实例时,只要我不尝试随它一起上传文件,它就可以工作。添加带有文件的发票会出现以下错误:

Internal Server Error: /stock/create_invoice
Traceback (most recent call last):
   File "/usr/local/lib/python3.8/dist-packages/django/core/handlers/exception.py", line 55, in inner
     response = get_response(request)
   File "/usr/local/lib/python3.8/dist-packages/django/core/handlers/base.py", line 197, in _get_response
     response = wrapped_callback(request, *callback_args, **callback_kwargs)
   File "/var/www/html/stock/views.py", line 346, in create_invoice
     invoice.save()
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/base.py", line 806, in save
     self.save_base(
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/base.py", line 857, in save_base
     updated = self._save_table(
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/base.py", line 1000, in _save_table
     results = self._do_insert(
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/base.py", line 1041, in _do_insert
     return manager._insert(
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/manager.py", line 85, in manager_method
     return getattr(self.get_queryset(), name)(*args, **kwargs)
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/query.py", line 1434, in _insert
     return query.get_compiler(using=using).execute_sql(returning_fields)
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/sql/compiler.py", line 1620, in execute_sql
     for sql, params in self.as_sql():
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/sql/compiler.py", line 1547, in as_sql
     value_rows = [
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/sql/compiler.py", line 1548, in <listcomp>
     [
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/sql/compiler.py", line 1549, in <listcomp>
     self.prepare_value(field, self.pre_save_val(field, obj))
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/sql/compiler.py", line 1497, in pre_save_val
     return field.pre_save(obj, add=True)
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/fields/files.py", line 316, in pre_save
     file.save(file.name, file.file, save=False)
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/fields/files.py", line 92, in save
     self.name = self.storage.save(name, content, max_length=self.field.max_length)
   File "/usr/local/lib/python3.8/dist-packages/django/core/files/storage.py", line 57, in save
     name = self._save(name, content)
   File "/usr/local/lib/python3.8/dist-packages/django/core/files/storage.py", line 339, in _save
     os.chmod(full_path, self.file_permissions_mode)
 PermissionError: [Errno 1] Operation not permitted: '/var/www/html/media/invoices/veryniceinvoice.pdf'
 Internal Server Error: /stock/invoice/0/
 Traceback (most recent call last):
   File "/usr/local/lib/python3.8/dist-packages/django/core/handlers/exception.py", line 55, in inner
     response = get_response(request)
   File "/usr/local/lib/python3.8/dist-packages/django/core/handlers/base.py", line 197, in _get_response
     response = wrapped_callback(request, *callback_args, **callback_kwargs)
   File "/usr/local/lib/python3.8/dist-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
     return view_func(request, *args, **kwargs)
   File "/var/www/html/stock/views.py", line 159, in invoice
     invoice = Invoice.objects.get(pk=invoice_id)
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/manager.py", line 85, in manager_method
     return getattr(self.get_queryset(), name)(*args, **kwargs)
   File "/usr/local/lib/python3.8/dist-packages/django/db/models/query.py", line 496, in get
     raise self.model.DoesNotExist(
      stock.models.Invoice.DoesNotExist: Invoice matching query does not exist.

文件已上传到正确的(cifs 安装)文件夹,但由于某些原因,无法将包含文件 link 的对象实例添加到数据库中?

我想问题是某种权限问题。我尝试通过将所有内容设置为 777 来解决此问题,因此我至少可以看到这是否解决了问题,但事实并非如此。当前 /var/www/html/media 的文件夹权限为:

drwxrwxrwx 2 root root 0 Mar 17 08:57 发票

chown 出于某种原因不起作用(我读到这与 cifs 挂载有关?),但 var-www 也不是以前服务器上发票文件夹的所有者,而且工作正常...

非常感谢任何帮助!

我找到了解决方案。

我必须将 uid=www-data,forceuid 添加到 cifs 挂载命令。 apache 用户没有正确的权限。

(然后卸载,再挂载)