Tutorial Deploy FlowSquad on Kubernetes with PostgreSQL and Pinecone: Production Checklist

Deploy FlowSquad on Kubernetes with PostgreSQL and Pinecone: Production Checklist

Helm values, environment secrets, persistent volume for ChromaDB, health probes, RBAC service accounts — everything needed for a production-grade K8s deployment of FlowSquad in one place.
TL;DR

What Are the Prerequisites for a Production FlowSquad Deployment?

Before running a single kubectl command, your cluster must meet a baseline that prevents the most common production failures. Teams that skip this step report spending an average of 6 extra hours diagnosing issues that the checklist below catches in seconds.

August 1, 2026 · 12 min read · DevOps EngineersPlatform Teams

Run the prerequisite validation script bundled with the chart: helm template flowsquad ./chart --dry-run --debug. If it exits 0, your values file is syntactically valid.

How Do You Structure the Helm Values File?

The Helm values file (values-prod.yaml) is the single source of truth for a production deployment. The chart exposes 47 values but only 12 are required for a functional cluster. The remainder control optional features like the LLM cost tracker, audit log retention, and horizontal pod autoscaler thresholds.

# values-prod.yaml — FlowSquad production Helm values
replicaCount: 3

image:
  repository: ghcr.io/flowsquad/flowsquad
  tag: "2.4.1"
  pullPolicy: IfNotPresent

ingress:
  enabled: true
  className: nginx
  host: flowsquad.internal.example.com
  tls:
    enabled: true
    secretName: flowsquad-tls

database:
  host: pg-primary.db.svc.cluster.local
  port: 5432
  name: flowsquad_prod
  sslMode: require
  poolSize: 20
  maxOverflow: 10

vectordb:
  provider: pinecone
  indexName: flowsquad-prod
  environment: us-east1-gcp

llm:
  defaultProvider: openai
  costTrackerEnabled: true

auth:
  mfaRequired: true
  saml:
    enabled: false   # enable for Keycloak SSO

resources:
  requests:
    cpu: "500m"
    memory: "1Gi"
  limits:
    cpu: "2000m"
    memory: "4Gi"

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 8
  targetCPUUtilizationPercentage: 65

Store this file in your GitOps repository alongside secrets.yaml (sealed or SOPS-encrypted). Never commit raw secrets. The 3-replica default ensures zero-downtime rolling updates; with maxUnavailable: 1, at least 2 pods serve traffic during deploys.

How Do You Configure PostgreSQL as the Primary Database?

PostgreSQL is FlowSquad's primary relational store for users, RBAC policies, epics, stories, tasks, audit logs, and LLM cost records. The schema is managed by Alembic migrations that run automatically in the init container before the app pod becomes ready.

The single most impactful tuning parameter is the connection pool. Load tests at 50 concurrent users show 3.2× more 500 errors when poolSize is left at the default of 5. Set it to at least 20 for teams over 10 engineers.

# Create the database and user
kubectl exec -it pg-primary-0 -- psql -U postgres <<'EOF'
CREATE DATABASE flowsquad_prod;
CREATE USER flowsquad WITH PASSWORD 'use-a-vault-secret';
GRANT ALL PRIVILEGES ON DATABASE flowsquad_prod TO flowsquad;
ALTER DATABASE flowsquad_prod OWNER TO flowsquad;
EOF

# Verify connectivity from inside the cluster
kubectl run pg-check --image=postgres:16 --restart=Never --rm -it -- \
  psql "postgresql://flowsquad:@pg-primary.db.svc.cluster.local:5432/flowsquad_prod?sslmode=require" \
  -c "SELECT version();"

Enable audit logs on the PostgreSQL side too: set log_statement = 'ddl' and log_min_duration_statement = 1000. This feeds the SOC 2 CC6 evidence package that FlowSquad's built-in audit trail references.

How Do You Set Up Pinecone VectorDB in Production?

Pinecone powers FlowSquad's AskProduct feature — semantic search over your codebase across all 11 supported languages. The index must be created before the app starts; FlowSquad validates index existence at boot and will refuse to start if dimensions mismatch.

# Python snippet — create Pinecone index before deploy
import pinecone

pinecone.init(api_key="YOUR_KEY", environment="us-east1-gcp")

if "flowsquad-prod" not in pinecone.list_indexes():
    pinecone.create_index(
        name="flowsquad-prod",
        dimension=1536,      # OpenAI ada-002; use 768 for Ollama
        metric="cosine",
        pod_type="p2.x1",    # production pod type
        replicas=2,
        shards=1
    )
print("Index ready:", pinecone.describe_index("flowsquad-prod"))

For teams using ChromaDB instead (self-hosted), mount a 50 GB PersistentVolumeClaim at /data/chroma. The Helm chart creates this PVC automatically when vectordb.provider: chromadb and vectordb.persistence.enabled: true. With 300,000 embedded code chunks, ChromaDB uses approximately 12 GB on disk.

How Do You Handle Secrets and Environment Variables Securely?

FlowSquad applies field-level encryption (Fernet/AES-128) to LLM API keys and database credentials at rest. However, these values still need to reach the pod at startup. Use Kubernetes Secrets (sealed with Sealed Secrets or SOPS) and mount them as environment variables — never bake them into the image.

# Required env vars — store in a K8s Secret named flowsquad-secrets
FLOWSQUAD_DB_PASSWORD=<postgres-password>
FLOWSQUAD_SECRET_KEY=<32-char-random-string>
FLOWSQUAD_ENCRYPTION_KEY=<fernet-key-base64>
FLOWSQUAD_OPENAI_API_KEY=<sk-...>
FLOWSQUAD_PINECONE_API_KEY=<pinecone-key>
FLOWSQUAD_PINECONE_ENVIRONMENT=us-east1-gcp

# Create the Secret from a local .env file (gitignored)
kubectl create secret generic flowsquad-secrets \
  --from-env-file=.env.prod \
  --namespace=flowsquad \
  --dry-run=client -o yaml | kubectl apply -f -

Reference the secret in values-prod.yaml under envFrom so the Helm chart mounts it automatically. Rotate the Fernet key quarterly; FlowSquad's admin panel includes a key rotation wizard that re-encrypts all stored secrets without downtime.

What Health Probes and RBAC Do You Need?

Three probes are required. The startupProbe gives Alembic migrations up to 90 seconds to complete before liveness kicks in — without it, Kubernetes kills pods mid-migration. The livenessProbe restarts deadlocked workers. The readinessProbe gates traffic until the LLM provider connection pool is warm.

# Probe configuration (already in the chart, shown for reference)
startupProbe:
  httpGet:
    path: /healthz/startup
    port: 8000
  failureThreshold: 30
  periodSeconds: 3        # 30 × 3s = 90s max startup window

livenessProbe:
  httpGet:
    path: /healthz/live
    port: 8000
  initialDelaySeconds: 5
  periodSeconds: 10
  failureThreshold: 3

readinessProbe:
  httpGet:
    path: /healthz/ready
    port: 8000
  initialDelaySeconds: 10
  periodSeconds: 5

For RBAC service accounts, FlowSquad needs a ServiceAccount with get/list/watch on ConfigMaps (for runtime config reloads) and get on Secrets (for the encryption key). No cluster-level permissions are needed — all access is namespace-scoped, satisfying least privilege requirements.

# Minimal RBAC for the FlowSquad service account
kubectl create serviceaccount flowsquad -n flowsquad
kubectl create role flowsquad-role \
  --verb=get,list,watch --resource=configmaps \
  --verb=get --resource=secrets \
  -n flowsquad
kubectl create rolebinding flowsquad-binding \
  --role=flowsquad-role \
  --serviceaccount=flowsquad:flowsquad \
  -n flowsquad

What Is the Complete Production Checklist?

#Checklist ItemCommand / ValidationStatus
1Kubernetes 1.27+ confirmedkubectl version --short✔ Required
2Helm 3.12+ installedhelm version✔ Required
3Namespace createdkubectl create ns flowsquad✔ Required
4PostgreSQL reachable & migratedkubectl logs job/flowsquad-migrate✔ Required
5Pinecone index dimension=1536Pinecone console✔ Required
6Secrets created in namespacekubectl get secret flowsquad-secrets✔ Required
7TLS cert issued by cert-managerkubectl get cert -n flowsquad✔ Required
8RBAC ServiceAccount boundkubectl auth can-i get secrets --as=system:serviceaccount:flowsquad:flowsquad✔ Required
9HPA configured (min 2, max 8)kubectl get hpa -n flowsquad✔ Required
10All 3 pods Readykubectl get pods -n flowsquad✔ Required
11Health endpoints return 200curl https://flowsquad.internal/healthz/ready✔ Required
1210-step setup wizard completedBrowser UI at /setup✔ Required
13LLM cost tracker enabledvalues-prod.yaml costTrackerEnabled: true⬡ Recommended
14MFA enforced for all usersAdmin panel → Auth settings⬡ Recommended
15Audit log retention ≥ 90 daysAdmin panel → Audit settings⬡ Recommended

Frequently Asked Questions

Can I use the FlowSquad Helm chart with ArgoCD or Flux?

Yes. The chart is a standard Helm 3 chart with no pre/post hooks that require direct kubectl access. ArgoCD users should set server.helm.valuesFileSchemes: "secrets" if using the Helm Secrets plugin. Flux users can use HelmRelease with a valuesFrom reference to a sealed Kubernetes Secret for the sensitive values.

What happens if my PostgreSQL pod restarts mid-migration?

Alembic migrations are transactional. Each migration step runs in a transaction; if the connection drops, the transaction rolls back and the migration job exits with a non-zero code. Kubernetes re-runs the init container automatically. Alembic's version table ensures already-applied migrations are skipped on the retry. Average recovery time is under 45 seconds.

How do I switch from ChromaDB to Pinecone after go-live?

FlowSquad ships a migration CLI: flowsquad vectordb migrate --from chromadb --to pinecone --index flowsquad-prod. It re-indexes all existing embeddings in batches of 500. For a typical project with 200,000 chunks, migration takes approximately 18 minutes. Update the Helm values (vectordb.provider: pinecone) and do a rolling restart after the migration completes.

How many replicas do I need for a 50-engineer team?

Benchmarks show each FlowSquad pod handles approximately 12 concurrent LLM requests before CPU saturation at the 2-vCPU limit. For 50 engineers with a peak concurrency factor of 0.3 (15 simultaneous sessions), 2 replicas are sufficient. Set HPA maxReplicas: 6 to handle burst without over-provisioning. Enable the LLM cost tracker to validate actual concurrency over the first 2 weeks.

Does FlowSquad support multiple Kubernetes namespaces for environment isolation?

Yes. The recommended pattern is one namespace per environment: flowsquad-staging and flowsquad-prod, each with its own Helm release, Secrets, and PostgreSQL database. RBAC policies and audit logs are completely isolated. The 10-step setup wizard generates environment-specific values.yaml files with a --env flag: flowsquad-setup --env staging.

dev.to Hashnode Medium LinkedIn