Skip to content

Recipes — S3 (local object storage)

doze embeds a pure-Go, S3-compatible server (gofakes3) — no Docker, no JVM, no LocalStack. It boots on the first request, persists to disk, and reaps when idle. Your AWS SDK code talks to it unchanged.

s3 "media" {
bucket "uploads" {}
bucket "thumbnails" {}
bucket "backups" {
versioning = true # honored by clients; the dev backend is best-effort
}
}

Declared buckets are created on boot (and re-created idempotently by doze sync). Your app can also CreateBucket at runtime.

The S3 server listens on the explicit port you declared (say 9000). Point the aws CLI at it with an explicit endpoint plus dummy credentials and a region:

Terminal window
export AWS_ENDPOINT_URL_S3=http://127.0.0.1:9000
export AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test AWS_REGION=us-east-1
aws s3 ls # the declared buckets
aws s3 cp ./logo.png s3://uploads/
aws s3 cp big.iso s3://backups/ # multipart, automatically
aws s3 ls s3://uploads/
aws s3 presign s3://uploads/logo.png # a working presigned GET URL
aws s3 rm s3://uploads/logo.png

s3api works too, for the lower-level operations:

Terminal window
aws s3api list-buckets --query 'Buckets[].Name'
aws s3api head-object --bucket uploads --key logo.png

The key detail for any localhost S3 (doze, MinIO, LocalStack) is path-style addressing — virtual-host style (bucket.localhost) can’t resolve locally. The endpoint, credentials, and region come from the env you exported above (or declare the app as a process block and doze injects them for you).

Go (aws-sdk-go-v2):

s3.NewFromConfig(cfg, func(o *s3.Options) {
o.BaseEndpoint = aws.String(os.Getenv("AWS_ENDPOINT_URL_S3"))
o.UsePathStyle = true
})

Node (aws-sdk v3):

new S3Client({
endpoint: process.env.AWS_ENDPOINT_URL_S3,
forcePathStyle: true,
})

Python (boto3):

boto3.client("s3",
endpoint_url=os.environ["AWS_ENDPOINT_URL_S3"],
config=Config(s3={"addressing_style": "path"}))

Run your app with the backends guaranteed up:

Terminal window
doze run -- <your app>

Works well: bucket create/list/delete, object put/get/list/delete, multipart uploads, and presigned URLs. Dev-grade / limited: object versioning, lifecycle rules, bucket policies, and IAM. doze’s S3 is a fast local convenience, not a production object store.

Terminal window
doze sleep media # sleep it (data kept)
# wipe its data and start clean:
doze reset media