I have followed multiple tutorials on how to use the DigitalOcean object storage known as DigitalOcean Spaces on my Django project but I'm not able to do it. Actually, I was using it before and it was working, after that I moved the static files to Contabo Object Storage, and apparently their CDN is pretty slow so when I decided to go back to DO, it does not work anymore, I even went to the commit where I had it working and copied the exact same code.
Here is the code I have on my settings.py:
from storages.backends.s3boto3 import S3Boto3Storage
class MediaStorage(S3Boto3Storage):
bucket_name = "XXXX"
class StaticStorage(S3Boto3Storage):
bucket_name = "XXXX"
DEFAULT_FILE_STORAGE = "nafssi.settings.MediaStorage"
STATICFILES_STORAGE = "nafssi.settings.StaticStorage"
AWS_ACCESS_KEY_ID = "XXXX"
AWS_SECRET_ACCESS_KEY = "XXX/XXXX/XXXXX"
AWS_S3_ENDPOINT_URL = "https://XXXX.fra1.digitaloceanspaces.com"
AWS_S3_OBJECT_PARAMETERS = {
"CacheControl": "max-age=86400",
}
MEDIA_URL = f"{AWS_S3_ENDPOINT_URL}/media/"
STATIC_URL = f"{AWS_S3_ENDPOINT_URL}/static/"
When I try python manage.py collectstatic
I have the following error:
You have requested to collect static files at the destination
location as specified in your settings.
This will overwrite existing files!
Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel: yes
Traceback (most recent call last):
File "D:\Data\Dropbox\D Drive\Toubib\Nafssi\Code\manage.py", line 22, in <module>
main()
File "D:\Data\Dropbox\D Drive\Toubib\Nafssi\Code\manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "D:\Data\Dropbox\D Drive\Toubib\Nafssi\Code\nafssienv\lib\site-packages\django\core\management\__init__.py", line 442, in execute_from_command_line
utility.execute()
File "D:\Data\Dropbox\D Drive\Toubib\Nafssi\Code\nafssienv\lib\site-packages\django\core\management\__init__.py", line 436, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "D:\Data\Dropbox\D Drive\Toubib\Nafssi\Code\nafssienv\lib\site-packages\django\core\management\base.py", line 412, in run_from_argv
self.execute(*args, **cmd_options)
File "D:\Data\Dropbox\D Drive\Toubib\Nafssi\Code\nafssienv\lib\site-packages\django\core\management\base.py", line 458, in execute
output = self.handle(*args, **options)
File "D:\Data\Dropbox\D Drive\Toubib\Nafssi\Code\nafssienv\lib\site-packages\django\contrib\staticfiles\management\commands\collectstatic.py", line 209, in handle
collected = self.collect()
File "D:\Data\Dropbox\D Drive\Toubib\Nafssi\Code\nafssienv\lib\site-packages\django\contrib\staticfiles\management\commands\collectstatic.py", line 135, in collect
handler(path, prefixed_path, storage)
File "D:\Data\Dropbox\D Drive\Toubib\Nafssi\Code\nafssienv\lib\site-packages\django\contrib\staticfiles\management\commands\collectstatic.py", line 368, in copy_file
if not self.delete_file(path, prefixed_path, source_storage):
File "D:\Data\Dropbox\D Drive\Toubib\Nafssi\Code\nafssienv\lib\site-packages\django\contrib\staticfiles\management\commands\collectstatic.py", line 278, in delete_file
if self.storage.exists(prefixed_path):
File "D:\Data\Dropbox\D Drive\Toubib\Nafssi\Code\nafssienv\lib\site-packages\storages\backends\s3boto3.py", line 463, in exists
self.connection.meta.client.head_object(Bucket=self.bucket_name, Key=name)
File "D:\Data\Dropbox\D Drive\Toubib\Nafssi\Code\nafssienv\lib\site-packages\botocore\client.py", line 535, in _api_call
return self._make_api_call(operation_name, kwargs)
File "D:\Data\Dropbox\D Drive\Toubib\Nafssi\Code\nafssienv\lib\site-packages\botocore\client.py", line 980, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (403) when calling the HeadObject operation: Forbidden
I even added some CORS permissions on DigitalOcean as follows:
I found the solution, by tweaking the configuration, the changes were mainly in the endpoint URL and the media and static urls, also I added the Region Name for it to work.
Here is the updated code:
from storages.backends.s3boto3 import S3Boto3Storage
class MediaStorage(S3Boto3Storage):
bucket_name = "XXXX"
class StaticStorage(S3Boto3Storage):
bucket_name = "XXXX"
DEFAULT_FILE_STORAGE = "XXXX.settings.MediaStorage"
STATICFILES_STORAGE = "XXXX.settings.StaticStorage"
AWS_ACCESS_KEY_ID = config("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = config("AWS_SECRET_ACCESS_KEY")
AWS_STORAGE_BUCKET_NAME = "XXXX"
AWS_S3_REGION_NAME = "fra1"
AWS_S3_ENDPOINT_URL = "https://fra1.digitaloceanspaces.com"
AWS_S3_OBJECT_PARAMETERS = {
"CacheControl": "max-age=86400",
}
MEDIA_URL = "https://XXXX.fra1.digitaloceanspaces.com/media/"
STATIC_URL = "https://XXXX.fra1.digitaloceanspaces.com/static/"