A DigitalOcean Spaces client for Mac that also handles MinIO
DigitalOcean Spaces and MinIO both implement the Amazon S3 API, so a single S3 client on your Mac can work with either, as well as with Amazon S3 itself. What changes between them is four settings: the endpoint, the region, whether the bucket goes in the hostname or the path, and how TLS is set up. This guide gives the right values for a DigitalOcean Spaces client on a Mac, then for a self-hosted MinIO server, and explains the errors you'll see when one of them is off.
The four settings that differ between S3 services
| Setting | Amazon S3 | DigitalOcean Spaces | MinIO |
|---|---|---|---|
| Endpoint | Built from the region | <region>.digitaloceanspaces.com | Your server's hostname |
| Region | Where the bucket lives, e.g. eu-west-2 | The data centre slug, e.g. nyc3 | us-east-1 unless configured otherwise |
| Addressing | Bucket in hostname | Bucket in hostname (path also works) | Bucket in path, unless a domain is configured |
| TLS | Public certificate | Public certificate | Whatever you configure |
DigitalOcean Spaces: what a Mac client needs
Endpoint and region
Each Spaces data centre has its own endpoint, named after the region slug: nyc3.digitaloceanspaces.com, ams3.digitaloceanspaces.com, fra1.digitaloceanspaces.com, sgp1.digitaloceanspaces.com and so on. Use the one for the region your bucket was created in; the control panel shows it on the bucket's page.
For the region in the request signature, use the same data centre slug, such as nyc3. Spaces also has a CDN hostname (<bucket>.<region>.cdn.digitaloceanspaces.com) for serving files to browsers. That's not an API endpoint; don't use it in a client.
Access keys
Spaces doesn't use your DigitalOcean API token for S3 requests. Create a Spaces access key in the control panel, which gives you an access key ID and a secret. The secret is shown once, so copy it into your client or password manager before leaving the page. If you can limit the key to the buckets it needs, do; a key that can only reach one bucket can't damage the others.
Addressing
Spaces accepts the bucket in the hostname (my-bucket.nyc3.digitaloceanspaces.com), which is the usual form. Switch to path style only if your bucket name contains dots, because a dotted name in the hostname won't match the wildcard TLS certificate.
DigitalOcean's Spaces documentation lists the current regions and covers bucket-level settings such as CORS and the CDN.
MinIO
MinIO is S3-compatible storage you run yourself, so you choose the settings. Three defaults matter to a client.
Path style is the default
MinIO expects the bucket in the path (minio.example.com/my-bucket/key) unless you've configured a domain for virtual-hosted requests with the MINIO_DOMAIN environment variable. Most clients need path style switched on for MinIO.
The region is us-east-1
Unless you've set a region in MinIO's configuration, it uses us-east-1, and a signature made for a different region fails.
Port and TLS
MinIO listens on port 9000 by default, and serves plain HTTP unless it finds a certificate. You can give MinIO a certificate directly (it looks for public.crt and private.key in its certs directory), but a common setup is a reverse proxy that terminates TLS on port 443 and forwards to MinIO locally. With nginx, the essentials are passing the original Host header, because S3 signatures cover it, and not limiting or buffering request bodies:
server {
listen 443 ssl;
server_name minio.example.com;
ssl_certificate /etc/letsencrypt/live/minio.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/minio.example.com/privkey.pem;
client_max_body_size 0;
proxy_buffering off;
proxy_request_buffering off;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:9000;
}
}
If the proxy rewrites the Host header, every request fails with a signature mismatch even though the keys are correct.
Setting up Spaces and MinIO in Wharf
Wharf handles Amazon S3 and S3-compatible storage through the same site editor as SFTP and FTP, and its custom endpoint is meant for exactly these services; the editor names DigitalOcean Spaces and MinIO alongside Cloudflare R2. Choose Amazon S3 as the protocol, then:
For Spaces
- Bucket: the bucket name only.
- Region: choose Other… in the region picker and type the slug, such as
nyc3. The field is free text for this reason. - Endpoint:
nyc3.digitaloceanspaces.com(a leadinghttps://is removed for you). - Put bucket in the path: off, unless the bucket name contains dots.
- Access key ID and Secret access key: from the Spaces key. The secret goes into your Mac's Keychain.
For MinIO
- Region:
us-east-1, or whatever your server is configured with. - Endpoint: the server's hostname, such as
minio.example.com. - Put bucket in the path: on. The editor's own note says it's required by MinIO and most self-hosted servers.
Wharf always connects to the endpoint over HTTPS on the standard port, and the Endpoint field takes a hostname rather than a host:port pair. For MinIO that means putting it behind TLS on port 443, as in the proxy example above, rather than pointing Wharf at port 9000. The certificate needs to be one your Mac trusts: a public one such as Let's Encrypt, or your own certificate authority added to Keychain Access and marked as trusted.
When you connect, Wharf makes one small listing request to check the keys, region and bucket together, so a mistake shows up immediately. Errors are reported in plain terms: a refused key, for example, produces "Access denied" with a suggestion to check the key and whether it may use this bucket. For anything less obvious, View › Server Log… (⌘⇧K) shows each request and the service's error response, along with the canonical request that was signed, which is the quickest way to spot a proxy changing a header.
Once connected, Spaces and MinIO work like any other site: drag and drop, Quick Look previews, and folder sync. Wharf's S3 support is described on the features page, and the Cloudflare R2 guide covers the third service named in the editor.
Common errors
- Signature does not match: wrong region, a secret pasted with a stray space, or (for MinIO behind a proxy) a rewritten
Hostheader. - Certificate or hostname errors: a dotted bucket name in virtual-hosted style, or a self-signed certificate the Mac doesn't trust.
- Bucket not found on MinIO: path style is off, so the bucket name was put in the hostname.
- Could not build a URL: the endpoint contains a port or a path. Enter the bare hostname.
Object storage also differs from a server in ways no client can hide: folders are key prefixes, renames are a copy and a delete, and there are no Unix permissions. The S3 client guide explains those differences, and the support page covers credentials and the Keychain.