Create the minio go-kit micro-lib module — a MinIO client as a launcher.Component with a launcher.Checkable interface and a BeforeStart bucket-init hook. This module follows the same pattern as postgres and valkey and will be imported by iron-dough-api to back product image storage.
Context
Iron Dough's product management feature (Feature 2) requires object storage for product images. MinIO is the chosen backend — S3-compatible, self-hosted via Docker Compose, deployed on the devtools-network. The module must be a reusable go-kit component so any future service can import it without re-implementing the wiring.
MinIO devtools instance:
API: http://minio:9000 (container DNS — never localhost)
Ping(ctx context.Context) error — used by the health check aggregator; call BucketExists on the configured bucket
Constructor: New(cfg Config) *Client — returns the unstarted component; Start performs actual initialization
BeforeStart bucket-init option: if the configured bucket does not exist, create it with private ACL during Start; log the creation
Expose func (c *Client) Native() *minio.Client — returns the underlying SDK client for callers that need direct access (e.g. PutObject, RemoveObject, PresignedGetObject)
Package doc comment on package minio
Unit test: mock transport to verify Start calls bucket check; verify Ping returns error when unreachable
README.md with usage example showing wiring into a launcher application
Success Criteria
go build ./... passes with no errors
go vet ./... passes
gofmt -l . returns no files
All exported symbols have doc comments
New → Start → Native() → PutObject sequence works against the devtools MinIO instance
Ping returns nil when MinIO is healthy; returns a descriptive error when the endpoint is unreachable
Bucket is created automatically on first Start if it does not exist
Reference
Pattern to follow: code.nochebuena.dev/go/valkey (launcher component + Checkable)
## Goal
Create the `minio` go-kit micro-lib module — a MinIO client as a `launcher.Component` with a `launcher.Checkable` interface and a `BeforeStart` bucket-init hook. This module follows the same pattern as `postgres` and `valkey` and will be imported by `iron-dough-api` to back product image storage.
## Context
Iron Dough's product management feature (Feature 2) requires object storage for product images. MinIO is the chosen backend — S3-compatible, self-hosted via Docker Compose, deployed on the `devtools-network`. The module must be a reusable go-kit component so any future service can import it without re-implementing the wiring.
MinIO devtools instance:
- API: `http://minio:9000` (container DNS — never `localhost`)
- Console: `http://minio:9001`
- Credentials: `minioadmin` / `minioadmin`
- Auth: AWS Signature V4 (handled by `minio-go/v7`)
- Health: `GET /minio/health/live → 200`
Reference ADR: `iron-dough-docs/docs/adr/adr-015-minio-object-storage.md`
## Tasks
- [ ] Initialize Go module at `code.nochebuena.dev/go/minio`
- [ ] Add dependency: `github.com/minio/minio-go/v7`
- [ ] Define `Config` struct
```go
type Config struct {
Endpoint string // e.g. "minio:9000"
AccessKey string
SecretKey string
UseSSL bool
Bucket string
}
```
- [x] Implement `Client` struct wrapping `*minio.Client` — satisfies `launcher.Component` and `launcher.Checkable`
- `Start(ctx context.Context) error` — initialize the minio-go client; verify connectivity via `BucketExists` or equivalent
- `Stop(ctx context.Context) error` — no-op (stateless client)
- `Ping(ctx context.Context) error` — used by the health check aggregator; call `BucketExists` on the configured bucket
- [x] Constructor: `New(cfg Config) *Client` — returns the unstarted component; `Start` performs actual initialization
- [x] `BeforeStart` bucket-init option: if the configured bucket does not exist, create it with private ACL during `Start`; log the creation
- [x] Expose `func (c *Client) Native() *minio.Client` — returns the underlying SDK client for callers that need direct access (e.g. `PutObject`, `RemoveObject`, `PresignedGetObject`)
- [x] Package doc comment on `package minio`
- [x] Unit test: mock transport to verify `Start` calls bucket check; verify `Ping` returns error when unreachable
- [x] `README.md` with usage example showing wiring into a `launcher` application
## Success Criteria
- `go build ./...` passes with no errors
- `go vet ./...` passes
- `gofmt -l .` returns no files
- All exported symbols have doc comments
- `New` → `Start` → `Native()` → `PutObject` sequence works against the devtools MinIO instance
- `Ping` returns nil when MinIO is healthy; returns a descriptive error when the endpoint is unreachable
- Bucket is created automatically on first `Start` if it does not exist
## Reference
- Pattern to follow: `code.nochebuena.dev/go/valkey` (launcher component + Checkable)
- MinIO Go SDK: https://github.com/minio/minio-go
- ADR-015: `iron-dough-docs/docs/adr/adr-015-minio-object-storage.md`
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Goal
Create the
miniogo-kit micro-lib module — a MinIO client as alauncher.Componentwith alauncher.Checkableinterface and aBeforeStartbucket-init hook. This module follows the same pattern aspostgresandvalkeyand will be imported byiron-dough-apito back product image storage.Context
Iron Dough's product management feature (Feature 2) requires object storage for product images. MinIO is the chosen backend — S3-compatible, self-hosted via Docker Compose, deployed on the
devtools-network. The module must be a reusable go-kit component so any future service can import it without re-implementing the wiring.MinIO devtools instance:
http://minio:9000(container DNS — neverlocalhost)http://minio:9001minioadmin/minioadminminio-go/v7)GET /minio/health/live → 200Reference ADR:
iron-dough-docs/docs/adr/adr-015-minio-object-storage.mdTasks
code.nochebuena.dev/go/miniogithub.com/minio/minio-go/v7ConfigstructClientstruct wrapping*minio.Client— satisfieslauncher.Componentandlauncher.CheckableStart(ctx context.Context) error— initialize the minio-go client; verify connectivity viaBucketExistsor equivalentStop(ctx context.Context) error— no-op (stateless client)Ping(ctx context.Context) error— used by the health check aggregator; callBucketExistson the configured bucketNew(cfg Config) *Client— returns the unstarted component;Startperforms actual initializationBeforeStartbucket-init option: if the configured bucket does not exist, create it with private ACL duringStart; log the creationfunc (c *Client) Native() *minio.Client— returns the underlying SDK client for callers that need direct access (e.g.PutObject,RemoveObject,PresignedGetObject)package minioStartcalls bucket check; verifyPingreturns error when unreachableREADME.mdwith usage example showing wiring into alauncherapplicationSuccess Criteria
go build ./...passes with no errorsgo vet ./...passesgofmt -l .returns no filesNew→Start→Native()→PutObjectsequence works against the devtools MinIO instancePingreturns nil when MinIO is healthy; returns a descriptive error when the endpoint is unreachableStartif it does not existReference
code.nochebuena.dev/go/valkey(launcher component + Checkable)iron-dough-docs/docs/adr/adr-015-minio-object-storage.md