Heroku 部署的 django 项目中没有 S3 媒体文件

No S3 media files in Heroku-deployed django project

我正在尝试通过 Amazon S3 在我的 Django 项目(托管在 Heroku 上)中提供静态和媒体文件。静态文件现在可以在本地和部署中正常使用,但媒体文件只能在本地使用。当由 localhost 提供服务时,我可以验证是否正在从我的存储桶中正确添加和提供文件,但在生产环境中保存和加载都不起作用。当我尝试提供媒体图像(我手动添加到存储桶中)时,我收到 403 访问被拒绝错误:

<Error>
    <Code>AccessDenied</Code>
    <Message>Access Denied</Message>
    <RequestId>7430A21BE321C26B</RequestId>
    <HostId>
        h/c1VQF57wrLJ7JdHXuJ8LCrQdZL9PfQZN4G38Ihg8UYCxSt0znbxWfiTSDxz0dCooQoqgW9tpw=
    </HostId>
</Error>

当我尝试保存文件(通过 Wagtail 图片上传)时,我得到了相当通用的 Internal Server Error - 500。我不知道问题是什么。我可以获取静态文件但不能获取媒体文件这一事实是令人困惑的部分原因(并且让我认为这不仅仅是权限错误)。以下是我认为可能与问题相关的内容。

编辑: 我意识到我的生产设置中有 DEBUG = True 来自调试不同的生产错误。当我将其设置为 False 时,我现在收到静态文件 媒体文件的 403 错误。

我的存储桶策略:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "PublicReadForGetBucketObjects",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::owen-tribune/*"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::494147019987:user/jtebert"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::owen-tribune",
                "arn:aws:s3:::owen-tribune/*"
            ]
        },
        {
            "Sid": "somethingElse",
            "Action": "s3:ListBucket",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::owen-tribune",
                "arn:aws:s3:::owen-tribune/*"
            ],
            "Principal": {
                "AWS": [
                    "arn:aws:iam::494147019987:user/jtebert"
                ]
            }
        }
    ]
}

settings.py的相关部分:

AWS_ACCESS_KEY_ID = '###########'
AWS_SECRET_ACCESS_KEY = '################'
AWS_S3_HOST = 's3-us-east-2.amazonaws.com'

#AWS_SECRET_ACCESS_KEY = env['AWS_SECRET_ACCESS_KEY']
#AWS_ACCESS_KEY_ID = env['AWS_ACCESS_KEY_ID']
AWS_STORAGE_BUCKET_NAME = 'owen-tribune'

AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME

STATICFILES_LOCATION = 'static'
STATICFILES_STORAGE = 'owen.custom_storages.StaticStorage'
STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION)

MEDIAFILES_LOCATION = 'media'
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)
DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage'

custom_storages.py 中的自定义存储:

# custom_storages.py
from django.conf import settings
from storages.backends.s3boto import S3BotoStorage

class StaticStorage(S3BotoStorage):
    location = settings.STATICFILES_LOCATION

class MediaStorage(S3BotoStorage):
    location = settings.MEDIAFILES_LOCATION

解决静态文件问题的原因是压缩器。我的生产设置中有以下代码:

STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'

COMPRESS_OFFLINE = True
COMPRESS_CSS_FILTERS = [
    'compressor.filters.css_default.CssAbsoluteFilter',
    'compressor.filters.cssmin.CSSMinFilter',
]
COMPRESS_CSS_HASHING_METHOD = 'content'

这仅在 debug 为 False 时起作用,这就是我使用 debug=True 正确获取静态文件的原因。关闭调试后,压缩的静态文件存储在应用程序中而不是 S3 存储桶中,但应用程序仍在 S3 中寻找压缩的静态文件。我通过简单地在设置中注释掉这些行来解决这个问题。

媒体文件现在也可以正确上传,但自动生成的调整大小仍然不起作用。我会 post 提出一个单独的问题,如果我得到解决,我会在这里更新。