DigitalOcean Spaces¶
DigitalOcean Spaces object storage for file uploads, avatars, and media. The extension registers a Spaces-backed implementation of the platform's FileStorageStrategy interface, deriving the S3-compatible endpoint from your Spaces region (https://<region>.digitaloceanspaces.com) and supporting an optional CDN URL for public objects. Core upload surfaces — avatar uploads, media uploads, presigned browser uploads, and the media-orphan purge — then read and write objects in your Space.
At a glance
| Extension id | digitalocean_spaces |
| Category | storage |
| Version | 0.1.0 |
| Provides | FileStorageStrategy implementation (registered as digitalocean_spaces) |
| External account | DigitalOcean — Spaces access key + secret key |
What It Provides¶
- File storage strategy —
DigitalOceanSpacesStorageStrategy, registered with the strategy resolver as aFileStorageStrategyimplementation nameddigitalocean_spaceswhen the extension activates, alongside the built-inlocalbackend. - The
FileStorageStrategyinterface covers four operations: upload bytes under a key (returns the public URL), delete an object, build a browser-accessible public URL for a key, and generate a presigned upload URL. - The implementation wraps the shared
S3Service(backend/vectis/core/s3.py): path-style requests ({endpoint}/{bucket}/{key}) signed with AWS Signature Version 4 overhttpx— no boto3/aiobotocore dependency. - Nothing else — the package contributes no webhook endpoints, Temporal workflows, schedules, admin pages, GraphQL fields, or event subscriptions.
Setup¶
- Once installed (or dev-linked in development), the extension is discovered at startup. Enable it for a channel from Settings > Extensions (per-channel activation via
ChannelExtension). - Set the environment variables the manifest's install hint names:
S3_REGION(e.g.nyc3),S3_ACCESS_KEY,S3_SECRET_KEY,S3_BUCKET. - Restart the API. The strategy is constructed once, at extension activation, from those application settings.
Configuration Reference¶
| Key | Type | Required | Secret | Description |
|---|---|---|---|---|
s3_region |
string | Yes | No | Spaces Region. Defaults to nyc3. |
s3_access_key |
string | Yes | No | Spaces Access Key |
s3_secret_key |
password | Yes | Yes | Spaces Secret Key |
s3_bucket |
string | Yes | No | Space Name |
s3_public_url |
string | No | No | CDN URL (optional) |
password-typed fields are encrypted at rest (Fernet) and masked as *** in the admin configuration form.
Configuration is read from the environment, not the admin form
The activation hook builds the strategy from application settings (environment variables / .env) with the same key names uppercased — S3_REGION, S3_ACCESS_KEY, S3_SECRET_KEY, S3_BUCKET, S3_PUBLIC_URL. The extension defines no hot_reload hook, so values saved through the admin configuration form are stored but nothing hands them to the already-registered strategy. Configure via environment variables and restart.
Permissions¶
The manifest declares no admin permissions (permissions=[]), so no role assignment is needed.
Operational Notes¶
- Who calls it — core resolves the active
FileStorageStrategyat call time for avatar uploads (POST /api/upload/avatar), media uploads (POST /upload), presigned upload URLs (GET /upload/presign), CMS image derivative generation, and the dailyvectis-gc-media-orphansTemporal schedule (GcMediaOrphansWorkflow), which physically deletes purged media objects through the active backend. - Which backend wins — every registered backend keeps its name (
local,digitalocean_spaces,s3, ...); when core resolves the storage strategy without naming one, the most recently registered implementation is returned. - Endpoint — always derived from the region as
https://<region>.digitaloceanspaces.com; unlike the Amazon S3 extension, there is no endpoint override. - Public URLs are
<base>/<key>, where the base is the CDN URL (S3_PUBLIC_URL) when set, otherwisehttps://<bucket>.<region>.digitaloceanspaces.com. - Presigned uploads —
generate_presigned_urlreturns a SigV4 query-string presignedPUTURL against the Spaces endpoint; theGET /upload/presignendpoint uses the default 3600-second expiry. - Uploads sign with
UNSIGNED-PAYLOADand a 60-second HTTP timeout; deletes treat a 404 as success (idempotent) with a 30-second timeout. - Avatar uploads fall back to the built-in
localbackend when the primary backend raises, so a misconfigured Space degrades rather than hard-fails that endpoint. - The three S3-compatible storage extensions — Amazon S3, MinIO, and DigitalOcean Spaces — all read the same
S3_*settings; configure the one that matches your provider. See also Storage Extensions in the developer guide.