Blobber
A Go library and CLI for securely pushing and pulling files to OCI container registries.
NOTE: This repository has been superceeded by blob. It's the same principle, but with a custom file format that's up to 1000x faster than estargz.
Blobber uses the eStargz format to enable listing and selective retrieval of files without downloading entire images. Listing and streaming require eStargz images; Blobber pushes eStargz by default.
Quick Start
curl -fsSL https://blobber.meigma.dev/install.sh | sh # Push a directory to a registry blobber push ./config ghcr.io/myorg/config:v1 # List files without downloading blobber list ghcr.io/myorg/config:v1
Installation
CLI
curl -fsSL https://blobber.meigma.dev/install.sh | shSee the installation docs for other options (Homebrew, Scoop, Nix, Go).
Library
go get github.com/meigma/blobber
Examples
CLI
# Push a directory to a registry blobber push ./config ghcr.io/myorg/config:v1 # Push with Sigstore signing blobber push --sign ./config ghcr.io/myorg/config:v1 # List files without downloading blobber list ghcr.io/myorg/config:v1 # Stream a single file to stdout blobber cat ghcr.io/myorg/config:v1 app.yaml # Pull all files to a local directory blobber pull ghcr.io/myorg/config:v1 ./output # Pull with signature verification blobber pull --verify \ --verify-issuer https://accounts.google.com \ --verify-subject dev@company.com \ ghcr.io/myorg/config:v1 ./output
Library
package main import ( "context" "fmt" "log" "os" "github.com/meigma/blobber" "github.com/meigma/blobber/sigstore" ) func main() { ctx := context.Background() // Create a client with Sigstore signing signer, _ := sigstore.NewSigner(sigstore.WithEphemeralKey()) client, err := blobber.NewClient(blobber.WithSigner(signer)) if err != nil { log.Fatal(err) } // Push a directory (automatically signed) digest, err := client.Push(ctx, "ghcr.io/myorg/config:v1", os.DirFS("./config")) if err != nil { log.Fatal(err) } fmt.Println(digest) // Create a client with signature verification verifier, _ := sigstore.NewVerifier( sigstore.WithIdentity("https://accounts.google.com", "dev@company.com"), ) verifiedClient, _ := blobber.NewClient(blobber.WithVerifier(verifier)) // Open an image (signature verified before access) img, err := verifiedClient.OpenImage(ctx, "ghcr.io/myorg/config:v1") if err != nil { log.Fatal(err) } defer img.Close() entries, _ := img.List() for _, e := range entries { fmt.Printf("%s (%d bytes)\n", e.Path(), e.Size()) } }
Features
- List without download - View file contents using only the eStargz table of contents
- Selective retrieval - Stream individual files via HTTP range requests
- Sigstore signing - Sign artifacts for supply chain security; verify before pulling
- Any OCI registry - Works with GHCR, Docker Hub, ECR, GCR, or self-hosted registries
- Compression options - gzip (default) or zstd
- Local caching - Cache blobs locally for faster repeated operations
Configuration
Blobber stores configuration in ~/.config/blobber/config.yaml (following XDG conventions).
# View current configuration blobber config # Create default config file blobber config init # Disable caching blobber config set cache.enabled false # Bypass cache for a single command blobber --no-cache pull ghcr.io/myorg/config:v1 ./output
Configuration precedence: flags > environment variables > config file > defaults.
Documentation
Full documentation is available at blobber.meigma.dev:
- CLI Getting Started
- Library Getting Started
- Signing & Verification
- CLI Reference
- Library Reference
- Configuration Guide
Authentication
Blobber uses Docker credentials from ~/.docker/config.json. If you can docker push to a registry, blobber can too.
License
MIT License - see LICENSE for details.