1

我们目前正在使用 AWS S3 存储桶作为 Django 1.11 项目中媒体文件的存储(使用S3BotoStorage来自django-storages库)。相关代码在这里:

# storage.py

from storages.backends.s3boto import S3BotoStorage


class MediaRootS3BotoStorage(S3BotoStorage):
    """Storage for uploaded media files."""
    bucket_name = settings.AWS_MEDIA_STORAGE_BUCKET_NAME
    custom_domain = domain(settings.MEDIA_URL)
# common_settings.py

DEFAULT_FILE_STORAGE = 'storage.MediaRootS3BotoStorage'
AWS_MEDIA_STORAGE_BUCKET_NAME = 'xxxxxxxxxxxxxxxx'
MEDIA_URL = "//media.example.com/"
# models.py
import os
import uuid

from django.db import models
from django.utils import timezone
from django.utils.module_loading import import_string


def upload_to_unique_filename(instance, filename):
    try:
        extension = os.path.splitext(filename)[1]
    except Exception:
        extension = ""
    now = timezone.now()

    return f'resume/{now.year}/{now.month}/{uuid.uuid4()}{extension}'


class Candidate(models.Model):
    [...]
    resume = models.FileField(
        storage=import_string(settings.DEFAULT_PRIVATE_FILE_STORAGE)(),
        upload_to=upload_to_unique_filename,
    )
    [...]

问题是存储桶密钥在设置文件中被硬编码,并且由于有多个开发人员 + 1 个暂存环境,所有为测试/QA 目的而上传的垃圾文件最终都与真实生产数据位于同一个 S3 存储桶中.

一种明显的解决方案是覆盖AWS_MEDIA_STORAGE_BUCKET_NAMEinstaging_settings.pydevelopment_settings.py文件,但这会使生产数据在暂存和测试实例上不可用。为了完成这项工作,我们会以某种方式将生产存储桶同步到开发/暂存存储桶,我不确定如何高效且无缝地完成。

另一种选择是在开发和登台环境中使用本地文件系统进行媒体存储。这还需要下载大量媒体文件,并将堆栈的一部分(django-storages和 S3 API)排除在测试/QA 过程之外。

如何处理?在同一个存储桶中混合测试和生产媒体文件是否是一个问题(在我开始考虑如何处理它之前,我确信这是一个问题)?一般来说,分离开发/登台/生产云存储有哪些最佳实践?

4

1 回答 1

1

在这种情况下,我们的团队对所有环境都使用一个存储桶,但我们会在上传的静态和媒体文件中添加一些元数据。通过这种方式,为了删除某种非生产 S3 对象,您可以使用 AWS API 进行过滤,然后删除它们。

可以通过在 settings.py 中添加:

ENVIRONMENT = "development/production/qa"
AWS_S3_OBJECT_PARAMETERS = {
   'CacheControl': 'max-age=86400',
   'Metadata': {
      'environment': ENVIRONMENT
   }
}
于 2022-01-13T16:54:39.453 回答