I have a Rails 6.1.6.1 app that is using Active Storage to upload images to Digital Ocean Spaces. All images are uploaded with public permissions. This has worked fine for over 2 years. I’ve now been adding video uploads as well, but using the exact same set up, all videos are uploaded as private instead, no matter what I do. Setting the video to public manually through the DO dashboard sets the permissions as expected.
My storage.yml
file is set up as follows:
digitalocean:
service: S3
access_key_id: <%= ENV["DIGITALOCEAN_SPACES_KEY"] %>
secret_access_key: <%= ENV["DIGITALOCEAN_SPACES_SECRET"] %>
region: <%= ENV["DIGITALOCEAN_SPACES_REGION"] %>
bucket: <%= ENV["DIGITALOCEAN_SPACES_BUCKET"] %>
endpoint: <%= ENV["DIGITALOCEAN_SPACES_ENDPOINT"] %>
public: true
upload:
cache_control: "public, max-age=31536000"
Where public: true
takes care of the permissions correctly for images.
Both images are videos are uploaded using Direct Upload through the same method.
When I upload an image it is send using the following url (with some bits redacted): https://[bucket].fra1.digitaloceanspaces.com/[file-id]?x-amz-acl=public-read&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=[key]%2F20230922%2Ffra1%2Fs3%2Faws4_request&X-Amz-Date=20230922T164911Z&X-Amz-Expires=300&X-Amz-SignedHeaders=content-length%3Bcontent-md5%3Bcontent-type%3Bhost&X-Amz-Signature=[signature]
. The important bit (I’m assuming) being x-amz-acl=public-read
When I upload a video the url is similar: https://[bucket].fra1.digitaloceanspaces.com/[file-id]?x-amz-acl=public-read&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=[key]%2F20230922%2Ffra1%2Fs3%2Faws4_request&X-Amz-Date=20230922T165148Z&X-Amz-Expires=300&X-Amz-SignedHeaders=content-length%3Bcontent-md5%3Bcontent-type%3Bhost&X-Amz-Signature=[signature]
. The same x-amz-acl=public-read
is present, yet it is private.
I’ve tried adding the x-amz-acl
header to the accepted headers in the DO Spaces settings. I’ve tried adding public: acl: "public-read"
to the storage.yml
. I’ve tried manually sending the header with every request. But at this point I feel like I’m fighting against something that should have just worked, in theory.
The images are all png or jpeg, the video is always an mp4. The images are limited to 2MB, but videos can of course be much larger (the smallest I’ve tried is 10MB), could it be related to file size somehow?
Any help would be much appreciated!
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Turns out I was looking for the answer in the wrong place. It wasn’t so much that videos were uploaded as private, all files were. Variants were public, but videos didn’t have variants. I’m still a bit puzzled why this is, since the
x-amz-acl=public-read
header was included. I am assuming it’s because the variant is processed directly through Rails, where as the original file is uploaded with DirectStorage.I ended up solving this by monkey patching @rails/activestorage to include the same header in the request. This is the patch (which you can use using the
patch-package
npm package):All in all not the most elegant solution, but after hours of debugging I’m just glad it works.