繁体   English   中英

在 Elastic Beanstalk Aws React Django 上托管站点时如何从单独的 S3 存储桶加载 static 文件

[英]How to load static files from separate S3 bucket when hosting site on Elastic Beanstalk Aws React Django

设置:在 Elastic Beanstalk 上托管的 React+Django。 Static 文件托管在单独的 S3 存储桶上。

我正在尝试使用src="/static/images/logo.png"加载图像。

在开发中它工作得很好,但在生产中它会向XXX.elasticbeanstalk.com/static/images/logo.png发送请求,而它应该请求Bucket.amazonaws.com/static/images/logo.png

同时,用户上传的媒体对于 POST 和 GET 请求都非常有效,图像是从 Bucket /media/路径存储和获取的。 我想避免根据环境有条件地编码绝对 url 路径。

我有一个 django production_settings.py文件:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

STATIC_ROOT = os.path.join(BASE_DIR, "..", "www", "static")
STATIC_URL = '/static/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

AWS_STORAGE_BUCKET_NAME = '****************'
AWS_S3_REGION_NAME = '****************' 
AWS_ACCESS_KEY_ID = '****************'
AWS_SECRET_ACCESS_KEY = '****************'


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



STATICFILES_LOCATION = 'static'
STATICFILES_STORAGE = 'custom_storages.StaticStorage'

MEDIAFILES_LOCATION = 'media'
DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage'

custom_storages.py

from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage


class StaticStorage(S3Boto3Storage):
    location = settings.STATICFILES_LOCATION


class MediaStorage(S3Boto3Storage):
    location = settings.MEDIAFILES_LOCATION

谢谢

似乎您的STATIC_URL设置不正确。 它指的是您的 web 应用程序项目路径,而不是 S3 存储桶 URL。 您可以尝试在下面使用它:

STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION)

你可以尝试什么..

1. 确保您拥有正确的 S3 权限和策略。 通过 AWS S3 控制台中的权限选项卡访问特定存储桶的“策略”。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<your_bucket_name>/*"
        },
        {
            "Sid": "Statement2",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::<your_bucket_name>/images/"
        }
    ]
}

2. 在你的项目环境中安装 WhiteNoiseMiddleware & django-storages。

pip install whitenoise
pip install django-storages

3. 在settings.py中将以下内容添加到MIDDLEWARE=

'whitenoise.middleware.WhiteNoiseMiddleware',

4. 需要在settings.py中添加以下内容才能正确处理来自 S3 的 URL。 处理由 django 中间件和 django-storages 自动完成

STATICFILES_LOCATION = 'static'
MEDIAFILES_LOCATION = 'media'

AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % os.environ['BUCKET_NAME']
AWS_ACCESS_KEY_ID = os.environ['AWS_KEY']
AWS_SECRET_ACCESS_KEY = os.environ['AWS_ACC_KEY']
AWS_STORAGE_BUCKET_NAME = os.environ['BUCKET_NAME']
AWS_S3_FILE_OVERWRITE = False
AWS_DEFAULT_ACL = None
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'

MEDIA_ROOT = os.path.join (BASE_DIR, 'static/images/')
STATIC_ROOT = os.path.join (BASE_DIR, 'static')

STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION)
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)

5. 用于瞄准上传到精确的 S3 Bucket 文件夹。 (额外的)

在 setting.py 中设置媒体根目录:

MEDIA_ROOT = os.path.join (BASE_DIR, 'static/images/')

在 models.py 中使用ImageFiled并添加upload_to=获取文件夹名称并在第一次上传时创建它:

image_variable = models.ImageField(null=True, default="{default_filename)", upload_to='uploads/') 

参考: django- storages , whiteNoiseMiddelware , S3 Access Troubleshooting

您已经扩展了 S3Boto3Storage ,您可以看到有多个参数,您可以为 static 存储 class 设置额外的 env 密钥:

class StaticStorage(S3Boto3Storage):
    location = settings.STATICFILES_LOCATION
    custom_domain = setting('AWS_S3_CUSTOM_DOMAIN_STATIC')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM