[英]How to load static files from separate S3 bucket when hosting site on Elastic Beanstalk Aws React Django
Setup: React+Django hosted on Elastic Beanstalk.设置:在 Elastic Beanstalk 上托管的 React+Django。 Static files hosted on separate S3 Bucket.
Static 文件托管在单独的 S3 存储桶上。
I'm trying to load an image using src="/static/images/logo.png"
.我正在尝试使用
src="/static/images/logo.png"
加载图像。
In development it works perfectly, but in production it sends a request to XXX.elasticbeanstalk.com/static/images/logo.png
while it should be requesting Bucket.amazonaws.com/static/images/logo.png
.在开发中它工作得很好,但在生产中它会向
XXX.elasticbeanstalk.com/static/images/logo.png
发送请求,而它应该请求Bucket.amazonaws.com/static/images/logo.png
。
Meanwhile the user uploaded media is working perfectly for both POST and GET requests, images are stored and fetched from the Bucket /media/
path.同时,用户上传的媒体对于 POST 和 GET 请求都非常有效,图像是从 Bucket
/media/
路径存储和获取的。 I want to avoid conditionally coding the absolute url path depending on the environment.我想避免根据环境有条件地编码绝对 url 路径。
I have a django production_settings.py
file:我有一个 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
: 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
Thanks谢谢
It seems like your STATIC_URL
set incorrectly.似乎您的
STATIC_URL
设置不正确。 It refers to your web app project path instead of S3 bucket URL.它指的是您的 web 应用程序项目路径,而不是 S3 存储桶 URL。 You can try using this below:
您可以尝试在下面使用它:
STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION)
What you can try..你可以尝试什么..
1. Make sure you have the right S3 Permissions and Policy in place. 1. 确保您拥有正确的 S3 权限和策略。 Access 'Policy' via permissions tab in AWS S3 console for your specific bucket.
通过 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. Install WhiteNoiseMiddleware & django-storages in your project environment. 2. 在你的项目环境中安装 WhiteNoiseMiddleware & django-storages。
pip install whitenoise
pip install django-storages
3. Add the following to MIDDLEWARE=
in settings.py
3. 在
settings.py
中将以下内容添加到MIDDLEWARE=
'whitenoise.middleware.WhiteNoiseMiddleware',
4. Following additions in settings.py
are required to handle URLs from S3 correctly. 4. 需要在
settings.py
中添加以下内容才能正确处理来自 S3 的 URL。 The handling is done by django middleware & django-storages automatically处理由 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. For aiming uploads into a precise S3 Bucket folder. 5. 用于瞄准上传到精确的 S3 Bucket 文件夹。 (Additional)
(额外的)
In setting.py set media root:在 setting.py 中设置媒体根目录:
MEDIA_ROOT = os.path.join (BASE_DIR, 'static/images/')
In models.py use ImageFiled
and add upload_to=
takes in a folder name and creates it with the first upload::在 models.py 中使用
ImageFiled
并添加upload_to=
获取文件夹名称并在第一次上传时创建它:
image_variable = models.ImageField(null=True, default="{default_filename)", upload_to='uploads/')
Reference: django-storages , whiteNoiseMiddelware , S3 Access Troubleshooting参考: django- storages , whiteNoiseMiddelware , S3 Access Troubleshooting
You have already extended S3Boto3Storage and you could see there is multiple parameters, you could set additional env key for static storage class:您已经扩展了 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.