# Object Storage

Source: https://docs.sliplane.io/object-storage/getting-started

Store files, uploads, backups, and other objects in S3-compatible buckets managed through Sliplane.

Sliplane Object Storage gives your team S3-compatible buckets for files, uploads, backups, generated assets, and other data that does not belong on a server volume.

## How it works

Object Storage is managed at the team level. Buckets are not tied to a specific project, server, or service.

Open **Object Storage** in the dashboard to manage buckets and their access keys.

## Regions

Object Storage is currently available in these regions:

| Region ID | Region  | City      |
| --------- | ------- | --------- |
| `ger`     | Germany | Frankfurt |
| `us-east` | US East | New York  |

Choose the region closest to your application or users.

## Create a bucket

In the dashboard, go to **Object Storage** and click **Create Bucket**.

Choose a bucket name, region, and whether you want to enable versioning or object locking.

Bucket names must follow S3 naming rules:

* 3 to 63 characters
* lowercase letters, numbers, dots, and hyphens
* must start and end with a letter or number
* must be globally unique

## Create an access key

Open a bucket and create an access key for it.

Access keys are scoped to exactly one bucket and have full read/write access to that bucket. They can list buckets and see whether other buckets exist in the same team, but they cannot access objects in other buckets.

> **warn**
>
> The secret access key is shown only once when the key is created. Store it securely before closing the dialog.

## Use the bucket

Use the bucket endpoint, bucket name, access key ID, and secret access key with any S3-compatible client.

### Configure your environment

Use AWS CLI v2 or a current AWS SDK. Configure the connection with **environment variables** or a named **profile**.

The examples set both region variables for compatibility with Boto3 and the other clients.

Copy the **endpoint URL** from your bucket in Sliplane.

#### Option 1: Environment variables

**Linux or macOS**

```bash
export AWS_ACCESS_KEY_ID="your_access_key_id"
export AWS_SECRET_ACCESS_KEY="your_secret_access_key"
export AWS_ENDPOINT_URL="https://your_bucket_endpoint"
export AWS_REGION="auto"
export AWS_DEFAULT_REGION="auto"
```

**Windows Command Prompt**

```bat
set "AWS_ACCESS_KEY_ID=your_access_key_id"
set "AWS_SECRET_ACCESS_KEY=your_secret_access_key"
set "AWS_ENDPOINT_URL=https://your_bucket_endpoint"
set "AWS_REGION=auto"
set "AWS_DEFAULT_REGION=auto"
```

**PowerShell**

```powershell
$Env:AWS_ACCESS_KEY_ID="your_access_key_id"
$Env:AWS_SECRET_ACCESS_KEY="your_secret_access_key"
$Env:AWS_ENDPOINT_URL="https://your_bucket_endpoint"
$Env:AWS_REGION="auto"
$Env:AWS_DEFAULT_REGION="auto"
```

#### Option 2: AWS profile

Add a named profile to your AWS configuration files. On Linux and macOS these live in `~/.aws/`; on Windows they live in `%USERPROFILE%\.aws\`.

`~/.aws/credentials`:

```ini title="~/.aws/credentials"
[sliplane]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key
```

`~/.aws/config`:

```ini title="~/.aws/config"
[profile sliplane]
endpoint_url = https://your_bucket_endpoint
region = auto
```

Then export the profile to your environment:

**Linux or macOS**

```bash
export AWS_PROFILE=sliplane
```

**Windows Command Prompt**

```bat
set "AWS_PROFILE=sliplane"
```

**PowerShell**

```powershell
$Env:AWS_PROFILE="sliplane"
```

> **info**
>
> If another AWS endpoint setting overrides your bucket URL, check [configuration precedence](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-endpoints.html#endpoints-precedence).

### Quick starts

Choose a client below:

**AWS CLI**

```bash
# List buckets
aws s3 ls

# Upload a file
aws s3 cp ./hello.txt s3://my-bucket/

# Download a file
aws s3 cp s3://my-bucket/hello.txt ./hello.txt
```

**JavaScript**

```javascript
import {
  S3Client,
  ListBucketsCommand,
  PutObjectCommand,
  ListObjectsV2Command,
  GetObjectCommand,
} from "@aws-sdk/client-s3"
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"

const s3 = new S3Client({})
const BUCKET_NAME = "my-bucket"

// List buckets
const { Buckets } = await s3.send(new ListBucketsCommand({}))
console.log(Buckets)

// Upload a file
await s3.send(
  new PutObjectCommand({
    Bucket: BUCKET_NAME,
    Key: "hello.txt",
    Body: "Hello, Sliplane!",
  }),
)

// List objects in the bucket
const list = await s3.send(
  new ListObjectsV2Command({ Bucket: BUCKET_NAME }),
)
console.log(list.Contents)

// Get a presigned URL for the object
const url = await getSignedUrl(
  s3,
  new GetObjectCommand({
    Bucket: BUCKET_NAME,
    Key: "hello.txt",
  }),
  { expiresIn: 120 },
)
console.log(url)
```

**Python**

```python
import boto3

s3 = boto3.client("s3")

# List buckets
for bucket in s3.list_buckets()["Buckets"]:
    print(bucket["Name"])

# Upload a file
s3.upload_file("./hello.txt", "my-bucket", "hello.txt")
```

**Go**

```go
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    ctx := context.Background()

    sdkConfig, err := config.LoadDefaultConfig(ctx)
    if err != nil {
        log.Fatalf("Load S3 configuration: %v", err)
    }

    s3Client := s3.NewFromConfig(sdkConfig)

    result, err := s3Client.ListBuckets(ctx, &s3.ListBucketsInput{})
    if err != nil {
        log.Fatalf("List Sliplane buckets: %v", err)
    }
    for _, b := range result.Buckets {
        fmt.Println(*b.Name)
    }
}
```

**Java**

```java
import software.amazon.awssdk.services.s3.S3Client;

public class HelloS3 {
    public static void main(String[] args) {
        S3Client s3 = S3Client.builder().build();

        s3.listBuckets().buckets().forEach(b -> System.out.println(b.name()));
    }
}
```

### AWS CLI and SDK guides

| Language or framework   | Library                                         | Documentation                                                                                                                                        |
| ----------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| CLI                     | AWS CLI                                         | [Custom endpoints in the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-endpoints.html)                                     |
| JavaScript / TypeScript | AWS SDK for JavaScript v3, `@aws-sdk/client-s3` | [Amazon S3 examples using SDK for JavaScript v3](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/javascript_s3_code_examples.html) |
| Python                  | boto3                                           | [boto3 S3 reference](https://docs.aws.amazon.com/boto3/latest/reference/services/s3.html)                                                            |
| Go                      | AWS SDK for Go v2, `service/s3`                 | [Amazon S3 examples using SDK for Go v2](https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/go_s3_code_examples.html)                         |
| Java                    | AWS SDK for Java 2.x                            | [Work with Amazon S3](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/examples-s3.html)                                              |
| .NET                    | AWS SDK for .NET, `AWSSDK.S3`                   | [Using Amazon S3 with the AWS SDK for .NET](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/s3-apis-intro.html)                           |
| PHP                     | AWS SDK for PHP                                 | [AWS SDK for PHP S3Client](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.S3.S3Client.html)                                                |
| Ruby                    | AWS SDK for Ruby, `aws-sdk-s3`                  | [AWS SDK for Ruby S3 client](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html)                                                     |
| Rust                    | AWS SDK for Rust, `aws-sdk-s3`                  | [Amazon S3 examples using SDK for Rust](https://docs.aws.amazon.com/sdk-for-rust/latest/dg/rust_s3_code_examples.html)                               |
| Kotlin                  | AWS SDK for Kotlin                              | [Work with Amazon S3 using the AWS SDK for Kotlin](https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/use-services-s3.html)           |
| Laravel                 | Laravel filesystem S3 driver                    | [Laravel S3 driver configuration](https://laravel.com/docs/filesystem#s3-driver-configuration)                                                       |
| Rails                   | Active Storage S3 service                       | [Rails Active Storage S3 service](https://guides.rubyonrails.org/active_storage_overview.html#s3-service-amazon-s3-and-s3-compatible-apis)           |
| Django                  | django-storages S3 backend                      | [django-storages Amazon S3 backend](https://django-storages.readthedocs.io/en/stable/backends/amazon-S3.html)                                        |

## API

You can also manage buckets and access keys through the [Sliplane API](https://ctrl.sliplane.io/#tag/buckets).

## Infrastructure provider

Object Storage is provided in partnership with [ImpossibleCloud GmbH](https://www.impossiblecloud.com/).
