feat(operator): add PowerSync and self-contained deployment - #13
Conversation
Complete design for extending cloudnative-supabase operator with three optional add-ons: - Sequin: CDC/event streaming (with Redis dependency) - Powersync: Offline-first sync (with auto CDC config) - Meilisearch: Full-text search Key decisions: - Operator-managed via optional CRD specs (presence = enabled) - Auto-generate all secrets (zero-config deployment) - Fully automatic CDC setup (roles, publications, schemas) - Hybrid Redis (external or bundled) - Production-ready defaults from flicknote-deploy - Deploy after core Supabase services Includes FlickNote reference example matching exact flicknote-deploy configuration.
Solution: Use dbmate migration Job (mirrors flicknote-deploy pattern) - ConfigMap with single migration (cdc_grants.sql) - Job runs after CNPG cluster ready (waits for auth.users table) - Custom migrations table (cloudnative_supabase_schema_migrations) - Idempotent via dbmate tracking Resolves open question from initial design. Reference: flick-backend-31/tanka/charts/db-init
… and CDC setup Add optional SequinSpec, PowersyncSpec, and MeilisearchSpec to SupabaseProject CRD. Implement Sequin secret generation (secretKeyBase, vaultKey, apiToken + DB role passwords), deployment builder with external Redis support, and CDC permissions Job using postgres psql for idempotent database creation and grant management. - CRD: Add SequinSpec, PowersyncSpec, MeilisearchSpec with ImageSpec, RedisSpec - Secrets: Auto-generate Sequin app secret + sequin/sequin_replication role passwords - Deployment: Sequin deployment with health probes, env from secrets, external Redis - Service: ClusterIP service with HTTP (7376) and metrics (4000) ports - CDC Job: Creates sequin database + applies replication grants after DB ready - CNPG: Extend cluster with sequin/sequin_replication managed roles when enabled - Controller: Add reconcileSequin, reconcileCDCPermissions, reconcileSequinSecrets - RBAC: Add batch/v1 Jobs permissions, controller owns Job resources - Status: Add SequinReady, CDCReady conditions and Sequin service status Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…fig, and controller - Add Powersync config.json ConfigMap builder with env var placeholders - Add sync rules ConfigMap builder (inline, configMapRef, or default) - Add Powersync API deployment (entry-api.js, client-facing, multi-replica) - Add Powersync Replication deployment (entry-replication.js, single instance) - Add Powersync Compact CronJob (entry-compact.js, configurable schedule) - Add Powersync API service (ports 8080 http + 9464 metrics) - Add Powersync secret generation and CNPG powersync_storage role - Extend CDC permissions Job for conditional Powersync grants - Add reconcilePowersync controller with ConfigMap, deployment, service, CronJob - Add CronJob RBAC permissions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… secrets, and controller - Add Meilisearch master key secret generation (auto-gen or user-provided) - Add MeilisearchMasterKey to SecretNamesStatus - Add Meilisearch StatefulSet builder with PVC, health probes, and env vars - Add Meilisearch service (port 7700) - Add reconcileMeilisearch controller with StatefulSet + Service - Add createOrUpdateStatefulSet helper (immutable VolumeClaimTemplates) - Add StatefulSet RBAC permissions - Wire into Phase 7 of reconcile loop Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Redis 7 StatefulSet builder (AOF persistence, non-root, TCP+CLI probes) - Add Redis ClusterIP service builder - Add RedisPersistenceSpec and Redis resources/storage to RedisSpec CRD - Add redis:7 image defaults - Update Sequin deployment to auto-resolve bundled Redis URL when external is nil - Add reconcileSequinRedis to controller (deploys when external Redis not configured) - Matches flicknote-deploy Redis chart pattern (security context, probes, 2Gi storage) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Sync Helm chart CRD with generated spec (Sequin, Powersync, Meilisearch types) - Add StatefulSet, Job, and CronJob RBAC to Helm chart ClusterRole - Update sample CR with commented examples for optional services Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 50 tests across 7 test files covering all new resource builders: - Sequin: deployment, env vars, external/bundled Redis URL resolution - Redis: StatefulSet, service, storage customization, security context - Powersync: API/Replication deployments, CronJob, env vars, volumes - Meilisearch: StatefulSet, PVC, master key secret ref, image pull secrets - Secrets: generation for Sequin/Powersync/Meilisearch, uniqueness - ConfigMaps: Powersync config JSON structure, sync rules (inline/external/default) - Services: port validation, labels/selectors for all new services Also add CDC & Search quick start documentation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PR workflow: lint (golangci-lint), test (pkg + resources), manifest check CI workflow: lint, test, then build+push via Dagger to in-cluster registry Dagger module builds Go binary in golang:1.25, packages into distroless container, and publishes to registry-docker-registry.arc-systems.svc:5000. Uses in-cluster Dagger engine for builds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tests Fix gofmt formatting, extract test constants to eliminate goconst/unparam warnings, fix staticcheck SA5011 nil-dereference patterns, rename shadowed import parameter, and lowercase error strings per ST1005. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix two critical bugs in CDC permissions reconciliation: 1. createOrCheckJob now returns (completed bool, err error) instead of just error. When the Job is still running, reconcileCDCPermissions sets CDCReady=False/Reason=JobRunning and requeues instead of prematurely setting CDCReady=True and deploying Sequin/Powersync. 2. A SHA-256 hash of the CDC setup script is stored as an annotation on the Job. When the spec changes (e.g., Powersync added after Sequin was already enabled), the hash mismatch triggers deletion of the old Job so a new one runs with the updated permissions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split Powersync's database concerns into two distinct roles: - powersync_storage: internal sync state tables (no REPLICATION) - powersync_replication: CDC/WAL reading (REPLICATION + BypassRLS) Previously powersync_storage was used for both the storage and replication connections, but lacked the REPLICATION privilege needed for logical replication. The replication URI now uses the dedicated powersync_replication role with proper credentials. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Review fixes are in c5739c3:
Verified locally with |
|
Scope correction in c990bc7: controller images now build and publish for linux/amd64 only. This replaces the earlier multi-architecture claim in the PR description. PR, main CI, release, and the Makefile default all exclude arm64; the delivery test enforces it. |
Triage UpdateFixed
False Positive
Deferred
Remaining
Local verification: |
|
CI follow-up: |
Triage CompleteFixed
False Positive
Deferred
Remaining
|
Summary
Tanka ownership
The
guionenvironment installs only the shared operator incnsupa-system. Application-specificSupabaseProjectresources remain in their application repositories. The old fd Flux operator manifests were already removed by fd commitc66d9bc; this PR does not change fd.Verification
make test test-tanka test-delivery./bin/golangci-lint-v2.5.0 run --timeout=5mgo build -o bin/manager cmd/main.goshellcheck hack/*.shtk fmt --test tankahelm lint charts/cloudnative-supabaseRelease note
The controller package is already public. After the first OCI chart release, a GuionAI org admin must make
guionai/charts/cloudnative-supabasepublic once; GitHub creates new package namespaces as private by default.