Plan: MinIO Object Storage

plan-2026-02-24-minio-object-storage Plan

pal-e-platform plan completed

Plan: MinIO Object Storage

Vision

Shared object storage for the pal-e cluster. MinIO provides S3-compatible storage that any service can consume — Litestream backups for SQLite databases, asset storage for docs, and future service needs. Deployed via Helm in pal-e-platform alongside Harbor, because object storage is infrastructure, not an application workload.

Projects & Repos Touched

Project/Repo Platform Role in this plan
<strong>pal-e-platform</strong> GitHub OpenTofu + Helm for MinIO deployment, Tailscale funnel
<strong>pal-e-docs</strong> Forgejo Consumer — Litestream sidecar (handled in Docs Foundation Phase 6)

Context

What's done:
  • k3s cluster stable with Tailscale funnels for ingress/TLS
  • Harbor deployed via Helm in pal-e-platform (same pattern MinIO followed)
  • ArgoCD + Image Updater operational in pal-e-services
  • pal-e-docs has 40+ notes, growing — SQLite database is precious
  • All 3 phases complete. MinIO deployed, console funneled, buckets + IAM created via Terraform provider.

Previous Plan

None — this is a new infrastructure capability. Triggered by plan-2026-02-24-docs-foundation Phase 6 (Litestream backup) needing an S3 target.

Depends On

Nothing — pal-e-platform is the foundation layer.

Decisions Made

Decision Rationale
<strong>MinIO in pal-e-platform, not pal-e-services</strong> Object storage is infrastructure, same tier as Harbor. Services consume it, they don't own it.
<strong>Helm chart, managed by OpenTofu</strong> Same pattern as Harbor. OpenTofu provisions the Helm release.
<strong>Tailscale funnel for MinIO console</strong> Public access to admin console for bucket/user management. Protected by MinIO's own auth.
<strong>Cluster-internal for S3 API</strong> Services hit <code>minio.minio.svc.cluster.local:9000</code>. No public exposure.
<strong>Chart: official minio from charts.min.io v5.4.0</strong> Standalone mode. 10Gi local-path PVC. 100m CPU, 256Mi-512Mi memory.
<strong>Phases 1+2 combined in single apply</strong> Funnel is just one extra resource.
<strong>MinIO Terraform provider (aminueza/minio) for bucket/IAM</strong> Declarative. Services request buckets via pal-e-platform issues.
<strong>S3 API ingress is tailnet-only, NOT funnel</strong> Console funnel (port 9001) doesn't handle S3/IAM API calls. Separate ingress on port 9000 needed for Terraform. But S3 API should NOT be public — removed <code>funnel = "true"</code> annotation so only tailnet members can reach it.

Phases

Phase 1: Deploy MinIO via Helm — COMPLETE

Completed 2026-02-26:
  • Helm release: standalone, 10Gi PVC, ServiceMonitor enabled
  • Pod healthy, services on 9000 + 9001
  • Credentials: ~/secrets/minio/credentials.env
  • Issue: issue-minio-phase-1 (resolved)

Phase 2: Tailscale Funnel for MinIO Console — COMPLETE

Completed 2026-02-26:
  • Console at https://minio.tail5b443a.ts.net, admin login verified

Phase 3: Create Initial Buckets — COMPLETE

Completed 2026-02-26:
  • MinIO Terraform provider (aminueza/minio v3.21.0) — 4th provider
  • S3 API tailnet-only ingress at minio-api.tail5b443a.ts.net
  • litestream-backups + assets buckets (private ACL)
  • litestream IAM user with scoped policy
  • Credentials: ~/secrets/minio/litestream.env
  • Issue: issue-minio-phase-3 (resolved)

Verification

  • [x] MinIO pod healthy in minio namespace
  • [x] MinIO console accessible at public Tailscale URL
  • [x] Can log in with admin credentials
  • [x] litestream-backups and assets buckets exist
  • [x] Service account with scoped access key created for Litestream
  • [ ] S3 API reachable from other pods: curl http://minio.minio.svc.cluster.local:9000

Status: COMPLETE

All phases done. Plan can be tagged completed after PR merged on pal-e-platform and internal S3 connectivity verified.

Next Plan Seeds

  • Litestream backup for pal-e-docs (plan-2026-02-24-docs-foundation Phase 6) — UNBLOCKED
  • Litestream for other SQLite services
  • Asset upload API for pal-e-docs notes
  • Remote OpenTofu state backend in MinIO
  • Harbor backup to MinIO
  • plan-2026-02-24-docs-foundation — Phase 6 NOW UNBLOCKED
  • project-pal-e-platform — where the Terraform lives
  • project-pal-e-docs — first consumer (Litestream backup)