Heroku部署的django项目

时间:2016-12-15 20:41:50

标签: django heroku amazon-s3 media

我正在尝试从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

1 个答案:

答案 0 :(得分:0)

静态文件问题的解决方案是由压缩器引起的。我的生产设置中有以下代码:

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中查找压缩的静态文件。我只是在设置中注释掉这些行来解决这个问题。

媒体文件现在也正确上传,但自动生成的大小调整仍无效。如果我得到解决方案,我会发布一个单独的问题并在此更新。