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  
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)  
}
Highlights:
- Works seamlessly with both S3 and MinIO
- Handles large files with automatic multipart uploads
- Just make sure S3ForcePathStyleis set totrue
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)  
}
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)  
}
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)