deploying-postgres-k8s
Deploys PostgreSQL on Kubernetes using the CloudNativePG operator with automated failover. Use when setting up PostgreSQL for production workloads, high availability, or local K8s development. Covers operator installation, cluster creation, connection secrets, and backup configuration. NOT when using managed Postgres (Neon, RDS, Cloud SQL) or simple Docker containers.
Best use case
deploying-postgres-k8s is best used when you need a repeatable AI agent workflow instead of a one-off prompt. It is especially useful for teams working in multi. Deploys PostgreSQL on Kubernetes using the CloudNativePG operator with automated failover. Use when setting up PostgreSQL for production workloads, high availability, or local K8s development. Covers operator installation, cluster creation, connection secrets, and backup configuration. NOT when using managed Postgres (Neon, RDS, Cloud SQL) or simple Docker containers.
Deploys PostgreSQL on Kubernetes using the CloudNativePG operator with automated failover. Use when setting up PostgreSQL for production workloads, high availability, or local K8s development. Covers operator installation, cluster creation, connection secrets, and backup configuration. NOT when using managed Postgres (Neon, RDS, Cloud SQL) or simple Docker containers.
Users should expect a more consistent workflow output, faster repeated execution, and less time spent rewriting prompts from scratch.
Practical example
Example input
Use the "deploying-postgres-k8s" skill to help with this workflow task. Context: Deploys PostgreSQL on Kubernetes using the CloudNativePG operator with automated failover. Use when setting up PostgreSQL for production workloads, high availability, or local K8s development. Covers operator installation, cluster creation, connection secrets, and backup configuration. NOT when using managed Postgres (Neon, RDS, Cloud SQL) or simple Docker containers.
Example output
A structured workflow result with clearer steps, more consistent formatting, and an output that is easier to reuse in the next run.
When to use this skill
- Use this skill when you want a reusable workflow rather than writing the same prompt again and again.
When not to use this skill
- Do not use this when you only need a one-off answer and do not need a reusable workflow.
- Do not use it if you cannot install or maintain the related files, repository context, or supporting tools.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/deploying-postgres-k8s/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How deploying-postgres-k8s Compares
| Feature / Agent | deploying-postgres-k8s | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Deploys PostgreSQL on Kubernetes using the CloudNativePG operator with automated failover. Use when setting up PostgreSQL for production workloads, high availability, or local K8s development. Covers operator installation, cluster creation, connection secrets, and backup configuration. NOT when using managed Postgres (Neon, RDS, Cloud SQL) or simple Docker containers.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Deploying PostgreSQL on Kubernetes
Deploy production-ready PostgreSQL clusters using CloudNativePG operator (v1.28+) with automated failover.
## Quick Start
```bash
# 1. Install CloudNativePG operator
kubectl apply --server-side -f \
https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.28/releases/cnpg-1.28.0.yaml
# 2. Wait for operator
kubectl rollout status deployment -n cnpg-system cnpg-controller-manager
# 3. Deploy PostgreSQL cluster
kubectl apply -f - <<EOF
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: pg-cluster
spec:
instances: 3
storage:
size: 10Gi
EOF
# 4. Wait for cluster
kubectl wait cluster/pg-cluster --for=condition=Ready --timeout=300s
```
## Operator Installation
### Direct Manifest (Recommended)
```bash
kubectl apply --server-side -f \
https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.28/releases/cnpg-1.28.0.yaml
# Verify
kubectl rollout status deployment -n cnpg-system cnpg-controller-manager
kubectl get pods -n cnpg-system
```
### Helm Installation
```bash
helm repo add cnpg https://cloudnative-pg.github.io/charts
helm repo update
helm upgrade --install cnpg \
--namespace cnpg-system \
--create-namespace \
cnpg/cloudnative-pg
```
### Namespace-Scoped (Enhanced Security)
```bash
helm upgrade --install cnpg \
--namespace cnpg-system \
--create-namespace \
--set config.clusterWide=false \
cnpg/cloudnative-pg
```
## Cluster Configurations
### Development (Single Instance)
```yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: pg-dev
spec:
instances: 1
imageName: ghcr.io/cloudnative-pg/postgresql:17.2
primaryUpdateStrategy: unsupervised
storage:
size: 5Gi
postgresql:
parameters:
max_connections: "100"
shared_buffers: "256MB"
```
### Production (HA with 3 Replicas)
```yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: pg-production
spec:
instances: 3
imageName: ghcr.io/cloudnative-pg/postgresql:17.2
primaryUpdateStrategy: unsupervised
storage:
storageClass: standard
size: 100Gi
resources:
requests:
memory: "2Gi"
cpu: "1"
limits:
memory: "4Gi"
cpu: "2"
postgresql:
parameters:
max_connections: "200"
shared_buffers: "1GB"
effective_cache_size: "3GB"
maintenance_work_mem: "256MB"
checkpoint_completion_target: "0.9"
wal_buffers: "16MB"
default_statistics_target: "100"
random_page_cost: "1.1"
effective_io_concurrency: "200"
affinity:
podAntiAffinityType: required # Spread across nodes
monitoring:
enablePodMonitor: true
```
### With Bootstrap Database
```yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: pg-cluster
spec:
instances: 3
storage:
size: 10Gi
bootstrap:
initdb:
database: learnflow
owner: app_user
secret:
name: app-user-secret
```
Create the secret first:
```bash
kubectl create secret generic app-user-secret \
--from-literal=username=app_user \
--from-literal=password=$(openssl rand -hex 16)
```
## Connection Secrets
CloudNativePG automatically creates connection secrets:
| Secret | Contents |
|--------|----------|
| `pg-cluster-app` | App credentials (recommended) |
| `pg-cluster-superuser` | Superuser credentials |
### Get Connection String
```bash
# Get app credentials
kubectl get secret pg-cluster-app -o jsonpath='{.data.uri}' | base64 -d
# Get superuser credentials (admin tasks only)
kubectl get secret pg-cluster-superuser -o jsonpath='{.data.uri}' | base64 -d
```
### Use in Deployment
```yaml
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: pg-cluster-app
key: uri
```
## Service Endpoints
| Service | Port | Use |
|---------|------|-----|
| `pg-cluster-rw` | 5432 | Read-Write (primary) |
| `pg-cluster-ro` | 5432 | Read-Only (replicas) |
| `pg-cluster-r` | 5432 | Any instance |
### Connect from Another Namespace
```yaml
env:
- name: DATABASE_URL
value: "postgresql://app_user:password@pg-cluster-rw.default.svc.cluster.local:5432/learnflow"
```
## Database Operations
### Connect with psql
```bash
# Using kubectl cnpg plugin (recommended)
kubectl cnpg psql pg-cluster -- -c "SELECT version();"
# Or directly
kubectl exec -it pg-cluster-1 -- psql -U postgres
```
### Create Database and User
```bash
kubectl exec -it pg-cluster-1 -- psql -U postgres <<EOF
CREATE DATABASE myapp;
CREATE USER myapp_user WITH ENCRYPTED PASSWORD 'secure_password';
GRANT ALL PRIVILEGES ON DATABASE myapp TO myapp_user;
\c myapp
GRANT ALL ON SCHEMA public TO myapp_user;
EOF
```
### Run Migrations
```bash
# From local machine
kubectl port-forward svc/pg-cluster-rw 5432:5432 &
DATABASE_URL="postgresql://postgres:password@localhost:5432/learnflow" alembic upgrade head
```
## Backup Configuration
### Backup to S3
```yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: pg-cluster
spec:
instances: 3
storage:
size: 10Gi
backup:
barmanObjectStore:
destinationPath: "s3://my-bucket/pg-backups"
s3Credentials:
accessKeyId:
name: s3-creds
key: ACCESS_KEY_ID
secretAccessKey:
name: s3-creds
key: SECRET_ACCESS_KEY
wal:
compression: gzip
data:
compression: gzip
retentionPolicy: "30d"
```
### Schedule Backups
```yaml
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: pg-backup-daily
spec:
schedule: "0 0 * * *" # Daily at midnight
backupOwnerReference: cluster
cluster:
name: pg-cluster
```
## Monitoring
### Check Cluster Status
```bash
kubectl get cluster pg-cluster
kubectl describe cluster pg-cluster
kubectl get pods -l cnpg.io/cluster=pg-cluster
```
### View Logs
```bash
kubectl logs pg-cluster-1 -f
kubectl logs -l cnpg.io/cluster=pg-cluster --all-containers
```
### Prometheus Metrics
With `enablePodMonitor: true`, metrics available at:
- `cnpg_backends_total` - Active connections
- `cnpg_pg_replication_lag_seconds` - Replica lag
- `cnpg_pg_database_size_bytes` - Database size
## Troubleshooting
### Cluster Not Ready
```bash
kubectl describe cluster pg-cluster
kubectl get pods -l cnpg.io/cluster=pg-cluster
kubectl logs pg-cluster-1
```
### Connection Issues
```bash
# Test connectivity
kubectl run pg-client --rm -it --restart=Never \
--image=postgres:17 -- \
psql "postgresql://app_user:password@pg-cluster-rw:5432/learnflow" -c "SELECT 1;"
```
### Common Issues
| Error | Cause | Fix |
|-------|-------|-----|
| PVC pending | No storage class | Add `storageClass` to spec |
| Connection refused | Wrong service name | Use `cluster-rw` for writes |
| Auth failed | Wrong credentials | Check secret `cluster-app` |
| Replica lag high | Heavy writes | Scale up, increase resources |
## Cleanup
```bash
# Delete cluster (keeps PVCs by default)
kubectl delete cluster pg-cluster
# Delete PVCs (data loss!)
kubectl delete pvc -l cnpg.io/cluster=pg-cluster
# Remove operator
kubectl delete -f \
https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.28/releases/cnpg-1.28.0.yaml
```
## Verification
Run: `python scripts/verify.py`
## Related Skills
- `operating-k8s-local` - Local Minikube cluster setup
- `scaffolding-fastapi-dapr` - FastAPI services with SQLModel
- `deploying-kafka-k8s` - Kafka for event-driven architectureRelated Skills
deploying-to-production
Automate creating a GitHub repository and deploying a web project to Vercel. Use when the user asks to deploy a website/app to production, publish a project, or set up GitHub + Vercel deployment.
postgresql-table-design
Design a PostgreSQL-specific schema. Covers best-practices, data types, indexing, constraints, performance patterns, and advanced features
supabase-postgres-best-practices
Postgres performance optimization and best practices from Supabase. Use this skill when writing, reviewing, or optimizing Postgres queries, schema designs, or database configurations.
postgresql-optimization
PostgreSQL database optimization workflow for query tuning, indexing strategies, performance analysis, and production database management.
postgres-best-practices
Postgres performance optimization and best practices from Supabase. Use this skill when writing, reviewing, or optimizing Postgres queries, schema designs, or database configurations.
azure-resource-manager-postgresql-dotnet
Azure PostgreSQL Flexible Server SDK for .NET. Database management for PostgreSQL Flexible Server deployments. Use for creating servers, databases, firewall rules, configurations, backups, and high availability. Triggers: "PostgreSQL", "PostgreSqlFlexibleServer", "PostgreSQL Flexible Server", "Azure Database for PostgreSQL", "PostgreSQL database management", "PostgreSQL firewall", "PostgreSQL backup", "Postgres".
azure-postgres-ts
Connect to Azure Database for PostgreSQL Flexible Server from Node.js/TypeScript using the pg (node-postgres) package. Use for PostgreSQL queries, connection pooling, transactions, and Microsoft Entra ID (passwordless) authentication. Triggers: "PostgreSQL", "postgres", "pg client", "node-postgres", "Azure PostgreSQL connection", "PostgreSQL TypeScript", "pg Pool", "passwordless postgres".
azure-postgres
Create new Azure Database for PostgreSQL Flexible Server instances and configure passwordless authentication with Microsoft Entra ID. Set up developer access, managed identities for apps, group-based permissions, and migrate from password-based to Entra ID authentication. Trigger phrases include "passwordless for postgres", "entra id postgres", "azure ad postgres authentication", "postgres managed identity", "migrate postgres to passwordless".
when-deploying-cloud-swarm-use-flow-nexus-swarm
Deploy cloud-based AI agent swarms with event-driven workflow automation using Flow Nexus platform. Supports hierarchical, mesh, ring, and star topologies with E2B sandbox distribution.
postgres-performance
High-performance PostgreSQL patterns. Use when optimizing queries, designing for scale, or debugging performance issues.
postgres-patterns
PostgreSQL patterns for reviewing migrations and writing efficient queries. Use when reviewing Alembic migrations, optimizing queries, or debugging database issues.
neon-postgres
Neon PostgreSQL serverless database - connection pooling, branching, serverless driver, and optimization. Use when deploying to Neon or building serverless applications.