# Object Storage Quick Start

Create your first S3-compatible bucket and start storing files in 5 minutes!

## Prerequisites

- A DanubeData account
- Basic familiarity with object storage concepts

## Step 1: Create a Bucket

### Via Dashboard

1. Navigate to **Object Storage** in the sidebar
2. Click **Create Bucket**
3. Enter your bucket configuration:
   - **Name**: `my-first-bucket` (lowercase, 3-63 characters)
   - **Region**: EU (Falkenstein) - default
   - **Versioning**: Disabled (can enable later)
   - **Public Access**: Disabled (recommended)
   - **Size Limit** (optional): Cap the bucket at 10 GB up to 5 TB, or leave it unlimited. You can change the cap later, but not below current usage.
   - **Object Lock** (optional): Enable write-once-read-many (WORM) protection. This can **only** be set at creation and turns on versioning automatically. See [Object Storage security](https://docs.danubedata.ro/object-storage-security#object-lock-worm).
4. Click **Create Bucket**

Your bucket will be ready in a few seconds!

### Via API

```bash
curl -X POST https://api.danubedata.ro/v1/storage/buckets \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-first-bucket",
    "region": "fsn1",
    "versioning_enabled": false,
    "public_access": false
  }'
```

## Step 2: Create Access Keys

Access keys are required to interact with your bucket via the S3 API.

### Via Dashboard

1. Navigate to your bucket's detail page
2. Click the **Access Keys** tab
3. Click **Create Access Key**
4. Configure the key:
   - **Name**: `my-app-key`
   - **Permissions**: Read & Write (or select specific permissions)
   - **Expiration**: Optional expiration date
5. Click **Create**
6. **Important**: Copy and save your Secret Key immediately - it won't be shown again!

### Via API

```bash
curl -X POST https://api.danubedata.ro/v1/storage/buckets/{bucket_id}/access-keys \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-app-key",
    "permissions": ["read", "write"]
  }'
```

Response:
```json
{
  "id": "key_abc123",
  "name": "my-app-key",
  "access_key": "AKIAIOSFODNN7EXAMPLE",
  "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
```

## Step 3: Configure Your S3 Client

### AWS CLI

Install the AWS CLI and configure it:

```bash
# Install AWS CLI (if not already installed)
pip install awscli

# Configure credentials
aws configure
# AWS Access Key ID: YOUR_ACCESS_KEY
# AWS Secret Access Key: YOUR_SECRET_KEY
# Default region name: fsn1
# Default output format: json
```

Create an alias for easier use:

```bash
# Add to ~/.bashrc or ~/.zshrc
alias danubedata-s3='aws --endpoint-url https://s3.danubedata.ro s3'
alias danubedata-s3api='aws --endpoint-url https://s3.danubedata.ro s3api'
```

### Environment Variables

Set up environment variables for your applications:

```bash
export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_KEY"
export AWS_ENDPOINT_URL="https://s3.danubedata.ro"
export AWS_REGION="fsn1"
```

## Step 4: Upload Your First File

### Using AWS CLI

```bash
# Upload a single file
aws --endpoint-url https://s3.danubedata.ro s3 cp hello.txt s3://my-first-bucket/

# Upload a directory
aws --endpoint-url https://s3.danubedata.ro s3 cp ./my-folder s3://my-first-bucket/my-folder/ --recursive

# Upload with custom metadata
aws --endpoint-url https://s3.danubedata.ro s3 cp document.pdf s3://my-first-bucket/ \
  --metadata '{"author":"john","department":"sales"}'
```

### Using the Dashboard

1. Navigate to your bucket
2. Click **Browse Objects** or the **Objects** tab
3. Click **Upload**
4. Drag and drop files or click to browse
5. Click **Upload**

### Using Python

```python
import boto3

s3 = boto3.client(
    's3',
    endpoint_url='https://s3.danubedata.ro',
    aws_access_key_id='YOUR_ACCESS_KEY',
    aws_secret_access_key='YOUR_SECRET_KEY'
)

# Upload a file
s3.upload_file('local-file.txt', 'my-first-bucket', 'remote-file.txt')
print("File uploaded successfully!")

# Upload with progress callback
from boto3.s3.transfer import TransferConfig

def progress_callback(bytes_transferred):
    print(f"Transferred: {bytes_transferred} bytes")

config = TransferConfig(use_threads=True)
s3.upload_file(
    'large-file.zip',
    'my-first-bucket',
    'large-file.zip',
    Config=config,
    Callback=progress_callback
)
```

## Step 5: Download Files

### Using AWS CLI

```bash
# Download a single file
aws --endpoint-url https://s3.danubedata.ro s3 cp s3://my-first-bucket/hello.txt ./

# Download a directory
aws --endpoint-url https://s3.danubedata.ro s3 cp s3://my-first-bucket/my-folder/ ./my-folder/ --recursive

# Sync a directory (only downloads new/changed files)
aws --endpoint-url https://s3.danubedata.ro s3 sync s3://my-first-bucket/data/ ./local-data/
```

### Using Python

```python
import boto3

s3 = boto3.client(
    's3',
    endpoint_url='https://s3.danubedata.ro',
    aws_access_key_id='YOUR_ACCESS_KEY',
    aws_secret_access_key='YOUR_SECRET_KEY'
)

# Download a file
s3.download_file('my-first-bucket', 'remote-file.txt', 'local-file.txt')

# Get file content directly
response = s3.get_object(Bucket='my-first-bucket', Key='hello.txt')
content = response['Body'].read().decode('utf-8')
print(content)
```

## Step 6: List Objects

### Using AWS CLI

```bash
# List all objects
aws --endpoint-url https://s3.danubedata.ro s3 ls s3://my-first-bucket/

# List with details
aws --endpoint-url https://s3.danubedata.ro s3 ls s3://my-first-bucket/ --human-readable --summarize

# List objects in a "folder"
aws --endpoint-url https://s3.danubedata.ro s3 ls s3://my-first-bucket/images/
```

### Using Python

```python
import boto3

s3 = boto3.client(
    's3',
    endpoint_url='https://s3.danubedata.ro',
    aws_access_key_id='YOUR_ACCESS_KEY',
    aws_secret_access_key='YOUR_SECRET_KEY'
)

# List objects
response = s3.list_objects_v2(Bucket='my-first-bucket')

for obj in response.get('Contents', []):
    print(f"{obj['Key']} - {obj['Size']} bytes - {obj['LastModified']}")
```

## Step 7: Generate Presigned URLs

Share files temporarily without exposing your credentials.

### Using Python

```python
import boto3
from datetime import datetime, timedelta

s3 = boto3.client(
    's3',
    endpoint_url='https://s3.danubedata.ro',
    aws_access_key_id='YOUR_ACCESS_KEY',
    aws_secret_access_key='YOUR_SECRET_KEY'
)

# Generate download URL (valid for 1 hour)
url = s3.generate_presigned_url(
    'get_object',
    Params={'Bucket': 'my-first-bucket', 'Key': 'document.pdf'},
    ExpiresIn=3600  # seconds
)
print(f"Download URL: {url}")

# Generate upload URL (valid for 1 hour)
upload_url = s3.generate_presigned_url(
    'put_object',
    Params={'Bucket': 'my-first-bucket', 'Key': 'uploads/new-file.txt'},
    ExpiresIn=3600
)
print(f"Upload URL: {upload_url}")
```

### Using AWS CLI

```bash
# Generate presigned URL (valid for 1 hour)
aws --endpoint-url https://s3.danubedata.ro s3 presign s3://my-first-bucket/document.pdf --expires-in 3600
```

## Step 8: Delete Objects

### Using AWS CLI

```bash
# Delete a single object
aws --endpoint-url https://s3.danubedata.ro s3 rm s3://my-first-bucket/hello.txt

# Delete multiple objects (folder)
aws --endpoint-url https://s3.danubedata.ro s3 rm s3://my-first-bucket/old-data/ --recursive

# Delete with confirmation
aws --endpoint-url https://s3.danubedata.ro s3 rm s3://my-first-bucket/important.txt --dryrun
```

### Using Python

```python
import boto3

s3 = boto3.client(
    's3',
    endpoint_url='https://s3.danubedata.ro',
    aws_access_key_id='YOUR_ACCESS_KEY',
    aws_secret_access_key='YOUR_SECRET_KEY'
)

# Delete single object
s3.delete_object(Bucket='my-first-bucket', Key='hello.txt')

# Delete multiple objects
s3.delete_objects(
    Bucket='my-first-bucket',
    Delete={
        'Objects': [
            {'Key': 'file1.txt'},
            {'Key': 'file2.txt'},
            {'Key': 'folder/file3.txt'},
        ]
    }
)
```

## Common Operations Cheat Sheet

| Operation | AWS CLI Command |
|-----------|-----------------|
| List buckets | `aws --endpoint-url https://s3.danubedata.ro s3 ls` |
| List objects | `aws --endpoint-url https://s3.danubedata.ro s3 ls s3://bucket/` |
| Upload file | `aws --endpoint-url https://s3.danubedata.ro s3 cp file.txt s3://bucket/` |
| Download file | `aws --endpoint-url https://s3.danubedata.ro s3 cp s3://bucket/file.txt ./` |
| Sync folder | `aws --endpoint-url https://s3.danubedata.ro s3 sync ./local s3://bucket/remote` |
| Delete file | `aws --endpoint-url https://s3.danubedata.ro s3 rm s3://bucket/file.txt` |
| Get bucket size | `aws --endpoint-url https://s3.danubedata.ro s3 ls s3://bucket/ --recursive --summarize` |

## Connecting over SFTP

If a tool or user needs SFTP instead of the S3 API, you can reach your bucket at `sftp.new-s3.danubedata.ro` on port `2222`. Create an SFTP user from the bucket's **SFTP** section — it reuses one of your S3 access keys, so its permissions match that key. The dashboard shows the exact username; the password is the access key's secret.

```bash
# Connect with any SFTP client (username shown in the dashboard)
sftp -P 2222 <sftp-username>@sftp.new-s3.danubedata.ro
```

## Next Steps

Now that you have your first bucket running, explore more features:

- [Object Storage Product Overview](https://docs.danubedata.ro/object-storage) - Full feature documentation
- [S3 Access Keys](https://docs.danubedata.ro/object-storage-access-keys) - Team-wide vs per-bucket scoped credentials
- [Object Storage Security](https://docs.danubedata.ro/object-storage-security) - Access control and encryption
- [Enable Versioning](https://docs.danubedata.ro/object-storage-versioning) - Protect against accidental deletion

## Troubleshooting

### "Access Denied" Error

- Verify your access key and secret key are correct
- Check that your access key has the required permissions
- Ensure the bucket name is correct (case-sensitive)

### "Bucket Not Found" Error

- Bucket names must be globally unique
- Verify the bucket name spelling
- Check you're using the correct endpoint (`https://s3.danubedata.ro`)

### Slow Uploads

- Use multipart upload for files larger than 100MB
- Enable `use_threads=True` in boto3 TransferConfig
- Check your network connection

### SSL Certificate Errors

- Ensure you're using `https://` not `http://`
- Update your SSL certificates: `pip install --upgrade certifi`

## Need Help?

- Check our [FAQ](../products/object-storage.md#faq)
- Contact support: support@danubedata.ro

---

**Congratulations!** You've successfully created your first bucket and uploaded files to DanubeData Object Storage!
