Skip to main content

Storage Configuration

Boards stores generated images, videos, audio, and other artifacts in object storage. This guide covers configuring the supported storage providers.

Supported Providers​

ProviderBest For
LocalDevelopment, single-server deployments
S3AWS deployments, S3-compatible services
GCSGoogle Cloud deployments
SupabaseWhen using Supabase for auth/database

Configuration File​

Create storage_config.yaml:

# Default provider for all operations
default_provider: s3

# Provider configurations
providers:
local:
type: local
base_path: /app/data/storage
public_url_base: http://localhost:8800/storage

s3:
type: s3
bucket: my-boards-bucket
region: us-east-1

gcs:
type: gcs
bucket: my-boards-bucket
project: my-gcp-project

supabase:
type: supabase
bucket: boards-storage

# Optional: File limits
max_file_size: 104857600 # 100MB

Set the config path:

BOARDS_STORAGE_CONFIG_PATH=/app/config/storage_config.yaml

Local Storage​

For development and single-server deployments:

providers:
local:
type: local
base_path: /app/data/storage
public_url_base: http://localhost:8800/storage

Mount a volume in Docker:

services:
api:
volumes:
- ./data/storage:/app/data/storage
warning

Local storage doesn't work with multiple API replicas unless using a shared filesystem (NFS, EFS).

Amazon S3​

Configuration​

providers:
s3:
type: s3
bucket: my-boards-bucket
region: us-east-1
# Optional: custom endpoint for S3-compatible services
# endpoint_url: https://s3.example.com

Environment Variables​

AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_REGION=us-east-1 # Optional if set in config

S3 Bucket Setup​

Create a bucket with appropriate permissions:

aws s3 mb s3://my-boards-bucket --region us-east-1

Bucket policy for public read access to artifacts:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-boards-bucket/*"
}
]
}

For private access (signed URLs), no bucket policy is needed.

CORS Configuration​

Enable CORS for browser uploads:

[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST"],
"AllowedOrigins": ["https://your-app.com"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]

IAM Policy​

Minimum permissions for the application:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-boards-bucket",
"arn:aws:s3:::my-boards-bucket/*"
]
}
]
}

S3-Compatible Services​

Boards works with S3-compatible services. Set the endpoint:

providers:
s3:
type: s3
bucket: my-bucket
region: auto
endpoint_url: https://s3.example.com

Compatible services:

  • MinIO
  • Cloudflare R2
  • DigitalOcean Spaces
  • Backblaze B2
  • Wasabi

Google Cloud Storage​

Configuration​

providers:
gcs:
type: gcs
bucket: my-boards-bucket
project: my-gcp-project

Authentication​

Set the service account credentials:

GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json

Or in Kubernetes with Workload Identity, the credentials are automatic.

Bucket Setup​

gsutil mb -p my-gcp-project -l us-central1 gs://my-boards-bucket

Public Access​

For public artifacts:

gsutil iam ch allUsers:objectViewer gs://my-boards-bucket

CORS Configuration​

cat > cors.json << EOF
[
{
"origin": ["https://your-app.com"],
"method": ["GET", "PUT", "POST"],
"responseHeader": ["Content-Type"],
"maxAgeSeconds": 3600
}
]
EOF

gsutil cors set cors.json gs://my-boards-bucket

IAM Permissions​

Required roles:

  • roles/storage.objectCreator - Upload files
  • roles/storage.objectViewer - Read files
  • roles/storage.objectAdmin - Full access (if deleting files)

Supabase Storage​

Configuration​

providers:
supabase:
type: supabase
bucket: boards-storage

Environment Variables​

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

Bucket Setup​

Create a bucket in Supabase dashboard:

  1. Go to Storage > New bucket
  2. Name: boards-storage
  3. Public: Enable for public artifacts

Or via SQL:

INSERT INTO storage.buckets (id, name, public)
VALUES ('boards-storage', 'boards-storage', true);

RLS Policies​

If using Row Level Security:

-- Allow authenticated uploads
CREATE POLICY "Allow uploads"
ON storage.objects FOR INSERT
TO authenticated
WITH CHECK (bucket_id = 'boards-storage');

-- Allow public reads
CREATE POLICY "Allow public reads"
ON storage.objects FOR SELECT
TO public
USING (bucket_id = 'boards-storage');

Advanced Configuration​

Routing Rules​

Route different artifact types to different providers:

default_provider: s3

providers:
local:
type: local
base_path: /app/data/cache
public_url_base: http://localhost:8800/cache
s3:
type: s3
bucket: my-boards-bucket
region: us-east-1

routing:
rules:
# Cache small files locally
- match:
max_size: 1048576 # 1MB
provider: local
# Videos always to S3
- match:
artifact_type: video
provider: s3

File Size Limits​

max_file_size: 104857600  # 100MB in bytes

Allowed Content Types​

allowed_content_types:
- image/jpeg
- image/png
- image/webp
- image/gif
- video/mp4
- video/webm
- audio/mpeg
- audio/wav
- application/json

CDN Integration​

For better performance, serve artifacts through a CDN:

CloudFront (S3)​

  1. Create a CloudFront distribution pointing to your S3 bucket
  2. Update the public URL:
providers:
s3:
type: s3
bucket: my-boards-bucket
region: us-east-1
public_url_base: https://d1234567890.cloudfront.net

Cloud CDN (GCS)​

  1. Create a load balancer with Cloud CDN enabled
  2. Point to your GCS bucket as backend
  3. Update the public URL in config

Troubleshooting​

Permission Denied​

  1. Verify credentials are set correctly
  2. Check IAM permissions on the bucket
  3. Ensure bucket exists and name is correct

CORS Errors​

  1. Configure CORS on the bucket
  2. Verify allowed origins match your domain
  3. Check browser console for specific error

Large File Uploads Failing​

  1. Check max_file_size configuration
  2. Verify network timeout settings
  3. Consider multipart upload for very large files

Next Steps​