DEV Community

Lamri Abdellah Ramdane
Lamri Abdellah Ramdane

Posted on

5 Best Go Libraries for Uploading Files to MinIO (Without Losing Your Mind)

Hey devs! Quick question — who among us hasn’t wrestled with file uploads and downloads in daily development? Images, videos, logs, backups… all that data needs a home. One great option? Object storage. And MinIO is one of the stars of the show.

MinIO is an open-source, self-hosted object storage service written in Go, fully compatible with Amazon S3’s API. Think of it as your own private S3 or Aliyun OSS — your data stays in your hands. Beautiful, right?

But before you enjoy all that convenience, you’ve got to get it running. And if you’ve seen the official Docker commands for MinIO — lots of parameters, mounts, and environment variables — you know it’s not exactly beginner-friendly. Docker port conflicts, persistence headaches, network settings… it’s enough to make you rage-quit.

That’s where ServBay comes to the rescue.

It supports all major languages (Python, Java, Go…), SQL and NoSQL databases, and even common services like MinIO. No need to wrestle with Docker commands or messy configs — just click a few times on ServBay’s panel, and boom — your MinIO server is up and running. More time for tea (or a nap).


Once MinIO is running, let’s talk code

If you’re using Go, here are 5 libraries that make uploading files to MinIO a breeze.


1. MinIO Official Go SDK (minio-go)

This is the official library maintained by MinIO itself — the “native” choice. It’s intuitive, reliable, and feature-rich.

Perfect if you’re building a project that only needs MinIO support.

Example:

package main  
import (  
    "context"  
    "log"  
    "github.com/minio/minio-go/v7"  
    "github.com/minio/minio-go/v7/pkg/credentials"  
)  

func main() {  
    ctx := context.Background()  
    minioHost := "127.0.0.1:9000"  
    accessKeyID := "minioadmin"  
    secretAccessKey := "minioadmin"  
    useSSL := false  

    minioClient, err := minio.New(minioHost, &minio.Options{  
        Creds:  credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),  
        Secure: useSSL,  
    })  

    if err != nil { log.Fatalln("Initialization failed:", err) }  

    bucketName := "learning-go"  
    objectName := "my-first-object.txt"  
    filePath := "./hello.txt"  

    exists, err := minioClient.BucketExists(ctx, bucketName)  
    if err != nil { log.Fatalln("Check bucket failed:", err) }  
    if !exists {  
        err = minioClient.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{})  
        if err != nil { log.Fatalln("Create bucket failed:", err) }  
        log.Printf("Bucket created: %s\n", bucketName)  
    }  

    uploadInfo, err := minioClient.FPutObject(ctx, bucketName, objectName, filePath, minio.PutObjectOptions{})  
    if err != nil { log.Fatalln("Upload failed:", err) }  

    log.Printf("Uploaded %s (%d bytes)\n", objectName, uploadInfo.Size)  
}

**Highlights:**
- Simple, direct API design  
- Comes with utilities for bucket management  
- Great documentation and community support  
Enter fullscreen mode Exit fullscreen mode

2. AWS SDK for Go (aws-sdk-go)

Since MinIO is S3-compatible, you can use the AWS SDK directly. This is especially useful if your project already uses AWS — you won’t have to rewrite your upload logic when switching to MinIO.

Example:

package main  
import (  
    "log"  
    "os"  
    "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/s3manager"  
)  

func main() {  
    minioEndpoint := "http://127.0.0.1:9000"  
    accessKey := "minioadmin"  
    secretKey := "minioadmin"  
    region := "us-east-1"  
    bucket := "go-aws-sdk-bucket"  
    localFilePath := "./hello.txt"  
    objectKey := "greeting.txt"  

    sess, err := session.NewSession(&aws.Config{  
        Credentials:      credentials.NewStaticCredentials(accessKey, secretKey, ""),  
        Endpoint:         aws.String(minioEndpoint),  
        Region:           aws.String(region),  
        S3ForcePathStyle: aws.Bool(true),  
    })  

    if err != nil { log.Fatalf("Session error: %v", err) }  

    file, err := os.Open(localFilePath)  
    if err != nil { log.Fatalf("File open error: %v", err) }  
    defer file.Close()  

    uploader := s3manager.NewUploader(sess)  
    _, err = uploader.Upload(&s3manager.UploadInput{  
        Bucket: aws.String(bucket),  
        Key:    aws.String(objectKey),  
        Body:   file,  
    })  

    if err != nil { log.Fatalf("Upload failed: %v", err) }  
    log.Printf("File uploaded to: %s/%s\n", bucket, objectKey)  
}
Enter fullscreen mode Exit fullscreen mode

Highlights:

  • Works seamlessly with both S3 and MinIO
  • Handles large files with automatic multipart uploads
  • Just make sure S3ForcePathStyle is set to true

3. Go Cloud (gocloud.dev)

Want cloud-agnostic code? Go Cloud lets you write once and run anywhere — today it’s MinIO, tomorrow Google Cloud Storage, next week Azure Blob Storage.

It provides a unified blob API to work with all major storage systems.

Example:

package main  
import (  
    "context"  
    "fmt"  
    "log"  
    "os"  
    "gocloud.dev/blob"  
    _ "gocloud.dev/blob/s3blob"  
)  

func main() {  
    minioHost := "127.0.0.1:9000"  
    accessKey := "minioadmin"  
    secretKey := "minioadmin"  
    bucketName := "gocloud-bucket"  
    localFile := "./hello.txt"  
    objectKey := "cloud-file.txt"  

    bucketURL := fmt.Sprintf("s3://%s?endpoint=%s&access_key_id=%s&secret_access_key=%s&disableSSL=true&s3ForcePathStyle=true", bucketName, minioHost, accessKey, secretKey)  

    ctx := context.Background()  
    b, err := blob.OpenBucket(ctx, bucketURL)  
    if err != nil { log.Fatalf("Open bucket failed: %v", err) }  
    defer b.Close()  

    data, err := os.ReadFile(localFile)  
    if err != nil { log.Fatalf("Read file failed: %v", err) }  

    err = b.WriteAll(ctx, objectKey, data, nil)  
    if err != nil { log.Fatalf("Upload failed: %v", err) }  

    log.Printf("File uploaded: %s/%s\n", bucketName, objectKey)  
}
Enter fullscreen mode Exit fullscreen mode

Highlights:

  • High portability
  • Extremely clean and abstracted API
  • Configuration via URL parameters

4. go-storage

Another storage abstraction library, similar in spirit to Go Cloud, but with a different design approach and community.

If Go Cloud’s style doesn’t click with you, this one might.

Example:

package main  
import (  
    "context"  
    "fmt"  
    "log"  
    "os"  
    "github.com/beyondstorage/go-storage/v5/services"  
    "github.com/beyondstorage/go-storage/v5/types"  
)  

func main() {  
    minioHost := "127.0.0.1:9000"  
    accessKey := "minioadmin"  
    secretKey := "minioadmin"  
    bucketName := "go-storage-bucket"  
    filePath := "./hello.txt"  
    objectName := "storage-api-file.txt"  

    connStr := fmt.Sprintf("s3://%s@%s?credential=hmac:%s:%s&endpoint=http://%s", bucketName, "us-east-1", accessKey, secretKey, minioHost)  
    store, err := services.NewStoragerFromString(connStr)  
    if err != nil { log.Fatalf("Create storager failed: %v", err) }  

    file, err := os.Open(filePath)  
    if err != nil { log.Fatalf("File open failed: %v", err) }  
    defer file.Close()  

    stat, _ := file.Stat()  
    fileSize := stat.Size()  

    _, err = store.Write(context.Background(), objectName, file, fileSize, types.WithForcePair(true))  
    if err != nil { log.Fatalf("Write failed: %v", err) }  

    log.Printf("Uploaded: %s/%s\n", bucketName, objectName)  
}
Enter fullscreen mode Exit fullscreen mode

Highlights:

  • Supports a wide range of backends
  • Uses connection strings for setup
  • Developer-friendly API

5. AWS SDK (Low-Level S3 Client)

If you need full control — metadata, ACLs, headers, fine-tuned upload options — you can drop down to AWS’s low-level S3 client.

It’s more verbose but gives you maximum flexibility.

Highlights:

  • Complete control over upload parameters
  • Ideal for fine-grained scenarios
  • Great for debugging and advanced use cases

Quick Comparison

Library Strengths Best For
minio-go Official, stable, full-featured New projects focused on MinIO
aws-sdk-go (s3manager) Large community, auto multipart upload AWS-based or hybrid projects
gocloud.dev Cloud-agnostic, clean API Multi-cloud or portable codebases
go-storage Flexible, connection-based setup Developers who prefer an alternative abstraction
aws-sdk-go (low-level) Full control, customizable Power users, fine-tuning scenarios

Final Thoughts

There’s no single “best” library — it all depends on your project’s needs and how much control or abstraction you want.

But one thing’s for sure: a stable, easy-to-manage MinIO environment is your foundation.

That’s why tools like ServBay are so helpful — they simplify setup so you can focus on writing great code, not configuring containers.

Your code (and your sanity) will thank you.

👉 Try ServBay and see how effortless it makes running MinIO and other services: servbay.com

Top comments (0)