Configuration
Configure Trove via YAML files, programmatic options, or environment variables.
Trove supports three configuration sources that merge in a defined order: YAML files, programmatic options, and built-in defaults. This gives you full flexibility to configure storage in any environment.
YAML Configuration
Add a trove key under extensions in your Forge config file:
# config.yaml
extensions:
trove:
driver_dsn: "file:///data/storage" # Storage driver DSN
grove_database: "default" # Named Grove DB from DI for metadata
base_path: "/trove/v1" # HTTP route prefix
disable_routes: false # Skip HTTP route registration
disable_migrate: false # Skip auto-migration
default_bucket: "default" # Default bucket name
cas_algorithm: "sha256" # CAS hash: sha256, blake3, xxhashThe extension also supports a top-level trove key for backward compatibility:
# Legacy format (still supported)
trove:
driver_dsn: "s3://my-bucket?region=us-east-1"The namespaced extensions.trove key is checked first. If not found, the extension falls back to the top-level trove key.
Multi-Store Configuration
Trove supports multiple named file stores, each with its own storage driver, metadata database, and settings. This mirrors how Grove supports multiple named databases.
extensions:
trove:
base_path: "/trove/v1"
stores:
- name: primary
storage_driver: "s3://us-east-1/my-bucket"
grove_database: "primary"
default_bucket: "uploads"
enable_compression: true
- name: archive
storage_driver: "file:///data/archive"
grove_database: "archive-db"
default_bucket: "archive"
- name: temp
storage_driver: "mem://"
default_bucket: "scratch"
default: primaryStore Entry Fields
| Field | Type | Description |
|---|---|---|
name | string | Unique identifier (required) |
storage_driver | string | DSN for the storage backend (required) |
grove_database | string | Named Grove DB for metadata |
default_bucket | string | Default bucket name |
enable_cas | bool | Enable content-addressable storage |
enable_encryption | bool | Auto-configure encryption middleware |
enable_compression | bool | Auto-configure compression middleware |
Default Store
The default field sets which store is used for unnamed DI injection (vessel.Inject[*trove.Trove]). If omitted, the first entry in stores becomes the default.
Validation
The configuration is validated during extension registration:
- Each store must have a
nameandstorage_driver - Store names must be unique
- If
defaultis set, it must reference an existing store name
Backward Compatibility
Single-store configuration (without the stores array) continues to work as before. The extension automatically detects whether to use single-store or multi-store mode based on whether stores is present.
Programmatic Options
Options set via troveext functions are merged with YAML configuration:
troveext.New(
troveext.WithBasePath("/storage/v1"),
troveext.WithConfig(troveext.Config{
DriverDSN: "file:///data/storage",
DefaultBucket: "uploads",
CASAlgorithm: "blake3",
}),
troveext.WithDisableRoutes(),
troveext.WithDisableMigrate(),
troveext.WithGroveDatabase("analytics-db"),
)Single-Store Options
| Function | Description |
|---|---|
troveext.WithBasePath(path) | Set the HTTP route prefix |
troveext.WithConfig(cfg) | Provide a full troveext.Config struct |
troveext.WithDisableRoutes() | Skip HTTP route registration |
troveext.WithDisableMigrate() | Skip automatic database migration |
troveext.WithGroveDatabase(name) | Use a named Grove DB from DI for metadata |
troveext.WithTroveOption(opt) | Add a trove.Option applied during initialization |
troveext.WithStore(s) | Provide a pre-built metadata store |
Multi-Store Options
| Function | Description |
|---|---|
troveext.WithFileStore(name, drv) | Add a named store with a pre-configured driver |
troveext.WithFileStoreDSN(name, dsn) | Add a named store using a DSN string |
troveext.WithDefaultFileStore(name) | Set which named store is the default |
troveext.WithTroveOptionFor(name, opt) | Add a trove.Option scoped to a named store |
Programmatic store entries take precedence over YAML entries with the same name.
Config Merge Behavior
Configuration sources merge in this order:
- YAML config --
extensions.trovekey, thentrovekey - Programmatic options -- Values set via option functions
- Defaults -- Built-in fallback values
YAML values take precedence over programmatic values for the same field. Programmatic values fill in anything YAML does not set. Boolean flags like disable_routes are additive: if either source sets it to true, it stays true.
Driver DSN Reference
The driver_dsn (or storage_driver in multi-store entries) field determines which storage backend Trove uses. Each driver is identified by a URI scheme:
| Driver | DSN Format | Example |
|---|---|---|
| Local filesystem | file:///path | file:///data/storage |
| Local filesystem | local://./relative/path | local://./storages/local |
| In-memory | mem:// | mem:// |
| Amazon S3 | s3://bucket?region=...&endpoint=... | s3://my-bucket?region=us-east-1 |
| Google Cloud Storage | gs://bucket | gs://my-bucket |
| Azure Blob Storage | azblob://container | azblob://my-container |
| SFTP | sftp://user@host/path | sftp://user@storage.example.com/data |
The local driver accepts both file:// (absolute paths) and local:// (relative paths) schemes. Relative paths are resolved from the current working directory.
S3-compatible stores (MinIO, DigitalOcean Spaces, Backblaze B2) use the s3:// scheme with the endpoint query parameter:
driver_dsn: "s3://my-bucket?region=us-east-1&endpoint=https://minio.local:9000"Driver Registry
Storage drivers register themselves in a global registry via their init() function. When Trove resolves a DSN, it extracts the scheme and looks up the corresponding driver factory. The following drivers are auto-registered when imported:
| Package | Registered Scheme(s) |
|---|---|
drivers/localdriver | file, local |
drivers/memdriver | mem |
drivers/s3driver | s3 |
drivers/gcsdriver | gcs |
drivers/azuredriver | azure |
drivers/sftpdriver | sftp |
In multi-store mode, ensure you import the driver packages your stores need so their init() functions register the factories.
Grove Database
The grove_database field tells Trove which Grove database instance to use for its metadata tables (buckets, objects, uploads, CAS index, quotas).
- If
grove_databaseis set, Trove resolves a named Grove DB:vessel.InjectNamed[*grove.DB](container, name) - If omitted or set to
"default", Trove uses the default Grove DB:vessel.Inject[*grove.DB](container)
This lets you run Trove metadata on a dedicated database separate from your application data by pointing grove_database at a named Grove database entry.
In multi-store mode, each store can reference a different Grove database. This keeps metadata isolated between stores.
Environment Variables
DSN values and other configuration strings can reference environment variables in your YAML config. This is handled by Forge's config loader:
extensions:
trove:
driver_dsn: "${TROVE_DRIVER_DSN}"
grove_database: "${TROVE_GROVE_DB:-default}"This keeps secrets out of config files and lets you vary configuration across environments without changing YAML.