Digital Ocean Spaces (their file store) supports the S3 api, but it has an asymmetrical opinion about bucket names. Consider the following config:
config :pleroma, Pleroma.Uploaders.S3,
bucket: "space_name/folder_name",
public_endpoint: "htttps://space_name.nyc3.digitaloceanspaces.com"
(Note: s3 creds via ex_aws
are configured as normal, albeit with DO's region naming scheme.)
In this case, if I have a Digital Ocean Space called space_name
, it lives at the above public endpoint. Spaces are sort of like buckets, but since each one on its own costs money you can't go horizontal with the buckets quite like you can on S3. For this reason, you're much more likely to always use a folder, as above.
With the above config, Pleroma.Uploaders.S3.put_item/1
will successfully save my images to folder_name
in the proper space. However, Pleroma.Uploaders.S3.get_item/1
uses the following code to try and get the url:
{:ok,
{:url,
Path.join([
Keyword.fetch!(config,:public_endpoint),
bucket_with_namespace,
strict_encode(URI.decode(file))
])}}
If no :namespace
opt is passed, the url is thus htttps://space_name.nyc3.digitaloceanspaces.com/space_name/folder_name/#{filename}
. If :bucket_namespace
opt is passed, it would be bucket_namespace:space_name/...
.
Yet for Digital Ocean, the proper URI for accessing filename
in folder_name
is htttps://space_name.nyc3.digitaloceanspaces.com/folder_name/#{filename}
. The prefix of space_name
on the public endpoint is all Digital Ocean accepts for accessing this particular "space", despite the fact that it accepts the space_name/folder_name
schema on put
.
I have added an option called :truncated_namespace
for this purpose which, when specified in the above config, truncates the path between :public_endpoint
and the :filename
to be solely that which is specified as a value.
config :pleroma, Pleroma.Uploaders.S3,
bucket: "space_name/folder_name",
public_endpoint: "htttps://space_name.nyc3.digitaloceanspaces.com",
truncated_namespace: "folder_name"
Which will yield htttps://space_name.nyc3.digitaloceanspaces.com/#{truncated_namespace}/#{filename}
.
The above config works with Digital Ocean Spaces given the MR'd code change. I was wishy-washy about the name of the opt, let me know if there is something more appropriate. I did not go with an opt name specific to Digital Ocean since this might be useful for other API's.