How to Use DigitalOcean Spaces with AWS S3 SDKs

Spaces Object Storage is an S3-compatible object storage service. Spaces buckets let you store and serve large amounts of data, and the built-in CDN minimizes page load times and improves performance.


The Spaces API is inter-operable with the AWS S3 API, meaning you can use existing S3 tools and libraries with Spaces. A common use case is managing Spaces buckets programmatically with AWS’ S3 Software Development Kits (SDKs). The S3 SDKs are available in a variety of languages and most are compatible with the Spaces API.

When using S3-focused tools, an S3 “key” is the name of a file in a bucket.

Setup and Configuration

Install the SDK

Install the AWS SDK using the package manager for your language of choice.

npm install @aws-sdk/client-s3
go get -u github.com/aws/aws-sdk-go
php composer.phar require aws/aws-sdk-php
pip install boto3
gem install aws-sdk-s3
dotnet add package AWSSDK.S3

Create Access Keys

To use the Spaces API, you need to create an access key and secret key for your bucket from the API page in the control panel.

The examples below rely on environment variables to access these keys. Export SPACES_KEY and SPACES_SECRET to your environment (for example, export SPACES_KEY=EXAMPLE7UQOTHDTF3GK4) to make them available to your code.

Configure a Client

To use Spaces with tools or libraries designed for the S3 API, you must configure the “endpoint” setting to point to buckets. The value should be ${REGION}.digitaloceanspaces.com where ${REGION} is the DigitalOcean datacenter region (for example, nyc3) where your bucket is located.

Note
To successfully create a new bucket, this SDK requires the region to be us-east-1, an AWS region name. The DigitalOcean datacenter region is based on the endpoint value, which is nyc3 in the example below.
import { S3 } from "@aws-sdk/client-s3";

const s3Client = new S3({
    forcePathStyle: false, // Configures to use subdomain/virtual calling format.
    endpoint: "https://nyc3.digitaloceanspaces.com",
    region: "us-east-1",
    credentials: {
      accessKeyId: process.env.SPACES_KEY,
      secretAccessKey: process.env.SPACES_SECRET
    }
});

export { s3Client };
Note
To successfully create a new bucket, this SDK requires the region to be us-east-1, an AWS region name. The DigitalOcean datacenter region is based on the endpoint value, which is nyc3 in the example below.
package main

import (
    "os"
    // Additional imports needed for examples below
    "fmt"
    "io"
    "strings"
    "time"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/credentials"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

func main() {
    key := os.Getenv("SPACES_KEY")
    secret := os.Getenv("SPACES_SECRET")

    s3Config := &aws.Config{
        Credentials: credentials.NewStaticCredentials(key, secret, ""),
        Endpoint:    aws.String("https://nyc3.digitaloceanspaces.com"),
        Region:      aws.String("us-east-1"),
        S3ForcePathStyle: aws.Bool(false), // // Configures to use subdomain/virtual calling format. Depending on your version, alternatively use o.UsePathStyle = false
    }

    newSession := session.New(s3Config)
    s3Client := s3.New(newSession)

    // ...
Note
To successfully create a new bucket, this SDK requires the region to be us-east-1, an AWS region name. The DigitalOcean datacenter region is based on the endpoint value, which is nyc3 in the example below.
<?php

// Included aws/aws-sdk-php via Composer's autoloader
require 'vendor/autoload.php';
use Aws\S3\S3Client;

$client = new Aws\S3\S3Client([
        'version' => 'latest',
        'region'  => 'us-east-1',
        'endpoint' => 'https://nyc3.digitaloceanspaces.com',
        'use_path_style_endpoint' => false, // Configures to use subdomain/virtual calling format.
        'credentials' => [
                'key'    => getenv('SPACES_KEY'),
                'secret' => getenv('SPACES_SECRET'),
            ],
]);
import os
import boto3

session = boto3.session.Session()
client = session.client('s3',
                        region_name='nyc3',
                        endpoint_url='https://nyc3.digitaloceanspaces.com',
                        aws_access_key_id=os.getenv('SPACES_KEY'),
                        aws_secret_access_key=os.getenv('SPACES_SECRET'))
Note
To successfully create a new bucket, this SDK requires the region to be us-east-1, an AWS region name. The DigitalOcean datacenter region is based on the endpoint value, which is nyc3 in the example below.
require 'aws-sdk-s3'

client = Aws::S3::Client.new(
  access_key_id: ENV['SPACES_KEY'],
  secret_access_key: ENV['SPACES_SECRET'],
  endpoint: 'https://nyc3.digitaloceanspaces.com',
  force_path_style: false, // Configures to use subdomain/virtual calling format.
  region: 'us-east-1'
)
using System;
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;

string accessKey = Environment.GetEnvironmentVariable("SPACES_KEY");
string secretKey = Environment.GetEnvironmentVariable("SPACES_SECRET");

AmazonS3Config config = new AmazonS3Config();
config.ServiceURL = "https://nyc3.digitaloceanspaces.com";

AmazonS3Client s3Client = new AmazonS3Client(
        accessKey,
        secretKey,
        config
        );
Warning

Due to an AWS-specific behavior in all versions of the SDK except Python 3, to successfully create a new bucket, you must specify an AWS region, such as us-east-1, in your configuration. This is because, when creating a bucket, the SDK sends an entirely different payload if a custom region is specified, which results in an error.

Specifying us-east-1 does not result in slower performance, regardless of your bucket’s location. The SDK checks the region for verification purposes but never sends the payload there. Instead, it sends the payload to the specified custom endpoint.

Calling S3 Commands

After your client has been configured, you can call any command in the S3 SDK that is supported by DigitalOcean Spaces. See the following topic for a complete list of supported commands:

The Spaces API is interoperable with the AWS S3 API. This list has all the S3 API commands supported by Spaces and their supported headers.
Warning
Using presigned URLs does not allow transferred files to be cached when using the Spaces CDN. Attempting to do so may result in double the bandwidth charge without the CDN’s performance benefit.

Additional Resources

For more details on compatibility with the S3 API, see the Spaces API documentation.

The full reference documentation for the SDKs used above can be found at: