Drive (Storage)
Nimbus Drive provides a unified API for file storage across multiple backends: local filesystem, Amazon S3, Google Cloud Storage, Cloudflare R2, DigitalOcean Spaces, and Supabase. It allows you to swap storage providers without changing your code.
Installation & Setup
Drive is included by default when creating a new app. If you need to add it manually, install the plugin and register it in bin/server.go:
import "github.com/CodeSyncr/nimbus/plugins/drive"
// Register the plugin (uses environment variables for configuration)
app.Use(drive.New(nil))
Configuration
Set DRIVE_DISK in your .env file to choose the active storage backend. Then, provide the necessary credentials for that specific provider.
| Backend | DRIVE_DISK value | Required Env Vars |
|---|---|---|
| Local Disk | fs (default) | None |
| Amazon S3 | s3 | S3_BUCKET, AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY |
| Google Cloud | gcs | GCS_BUCKET, GCS_KEY |
| Cloudflare R2 | r2 | R2_BUCKET, R2_ENDPOINT, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY |
| DO Spaces | spaces | SPACES_BUCKET, SPACES_ENDPOINT, SPACES_KEY, SPACES_SECRET |
| Supabase | supabase | SUPABASE_STORAGE_BUCKET, SUPABASE_STORAGE_URL, SUPABASE_STORAGE_KEY |
Usage
The drive.Use(disk) function returns a standard storage.Driver interface. Passing an empty string "" automatically uses the default disk specified by DRIVE_DISK.
import "github.com/CodeSyncr/nimbus/plugins/drive"
func handleUpload(c *http.Context) error {
file, err := c.Request.FormFile("avatar")
// ... handle err
// Get the default configured disk (e.g., S3 in production, fs locally)
disk, err := drive.Use("")
// Store the file
err = disk.Put("avatars/user-1.jpg", file)
// Get the public URL for the newly stored file
url, _ := disk.GetUrl("avatars/user-1.jpg")
return c.JSON(200, map[string]string{"url": url})
}
Disk Operations API
| Method | Signature | Description |
|---|---|---|
Put | Put(path string, reader io.Reader) error | Writes a file to the configured disk. Automatically creates parent directories locally. |
Get | Get(path string) (io.ReadCloser, error) | Streams the file for reading. You must Close() it when finished. |
Delete | Delete(path string) error | Removes the file. |
Exists | Exists(path string) (bool, error) | Checks if the file exists on the disk. |
GetUrl | GetUrl(path string) (string, error) | Returns a public URL for the file. For local fs, it prefixes with your RouteBasePath (e.g., /uploads/...). |
GetSignedUrl | GetSignedUrl(path string, dur time.Duration) | Generates a temporary, secure URL valid for the specified duration (e.g. for private cloud buckets). |
Local Disk Routing
When using the fs driver, Drive will store files in storage/app. The plugin automatically registers a static route to serve these files over HTTP if you enable it. By default, it mounts at /uploads.
To disable serving files or change the route, configure it in the plugin initialization:
app.Use(drive.New(&drive.Config{
DefaultDisk: "fs",
ServeFiles: true, // automatically serve files via HTTP
RouteBasePath: "/media", // files will be served at /media/*
}))
Switching Disks Manually
If your app interacts with multiple storage backends simultaneously (e.g., storing user avatars locally but archiving invoices to S3), you can request a specific disk by name:
// Uses the backend defined by DRIVE_DISK
defaultDisk, _ := drive.Use("")
// Forces the S3 backend
s3Disk, err := drive.Use("s3")
err = s3Disk.Put("archives/2026/invoice.pdf", file)
// Forces local filesystem
localDisk, err := drive.Use("fs")
err = localDisk.Put("temp/cache.json", file)
Advanced: Raw Storage Driver
If you are building a CLI tool or a script that completely bypasses the Drive plugin and its cloud features, you can instantiate the low-level storage.LocalDriver manually. This is not recommended for normal web applications.
import "github.com/CodeSyncr/nimbus/storage"
func advanced() {
driver := storage.NewLocalDriver("storage/app")
// Low-level methods
err := driver.Put("uploads/photo.jpg", file)
ok, _ := driver.Exists("uploads/photo.jpg")
driver.Delete("uploads/photo.jpg")
rc, err := driver.Get("uploads/photo.jpg")
if err == nil {
defer rc.Close()
// read from io.ReadCloser
}
}
Unlike drive, the raw storage.LocalDriver has no concept of public URLs (GetUrl) or signed URLs. It only handles raw file I/O within a specified root directory.