Self-host dengan Kubernetes
Cocok untuk team yang sudah punya K8s cluster (GKE, EKS, AKS, DigitalOcean, atau self-managed).
Prerequisites
- Cluster Kubernetes 1.28+
kubectlconfigured- Ingress controller (nginx-ingress, traefik, atau cloud-managed)
- cert-manager (untuk TLS otomatis) — opsional tapi direkomendasikan
- PostgreSQL 15+ (bisa in-cluster pakai operator, atau managed RDS/Cloud SQL)
Quick deploy
# Clone public distributiongit clone https://github.com/RenzyArmstrong/Calvery-Vault.gitcd Calvery-Vault/deploy/k8s
# Generate secretskubectl create namespace cvsm
kubectl -n cvsm create secret generic cvsm-env \ --from-literal=JWT_SECRET=$(openssl rand -hex 32) \ --from-literal=ENCRYPTION_KEY=$(openssl rand -hex 32) \ --from-literal=DATABASE_URL='postgres://cvsm:PASS@db:5432/cvsm' \ --from-literal=SMTP_PASSWORD='re_xxxxxxxx'
# Apply manifestskubectl apply -f postgres.yaml # skip kalau pakai managed DBkubectl apply -f api.yamlkubectl apply -f ingress.yamlArchitecture
┌─────────────────────────────────────────────┐│ Ingress (nginx/traefik) + cert-manager ││ vault.company.com │└────────────┬────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────┐│ Service: cvsm-api (ClusterIP) │└────────────┬────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────┐│ Deployment: cvsm-api (2-3 replicas) ││ - containerPort: 8080 ││ - readinessProbe: /health ││ - resources: 100m CPU, 128Mi RAM │└────────────┬────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────┐│ StatefulSet: postgres (1 replica) ││ - PersistentVolumeClaim 10Gi │└─────────────────────────────────────────────┘Example manifests
Deployment + Service
apiVersion: apps/v1kind: Deploymentmetadata: name: cvsm-api namespace: cvsmspec: replicas: 2 selector: matchLabels: { app: cvsm-api } template: metadata: labels: { app: cvsm-api } spec: containers: - name: api image: ghcr.io/renzyarmstrong/cvsm-api:v0.1.0 ports: - containerPort: 8080 envFrom: - secretRef: name: cvsm-env env: - name: APP_URL value: "https://vault.company.com" - name: ALLOWED_ORIGINS value: "https://vault.company.com" resources: requests: { cpu: 100m, memory: 128Mi } limits: { cpu: 500m, memory: 512Mi } readinessProbe: httpGet: { path: /health, port: 8080 } initialDelaySeconds: 5 livenessProbe: httpGet: { path: /health, port: 8080 } periodSeconds: 30---apiVersion: v1kind: Servicemetadata: name: cvsm-api namespace: cvsmspec: selector: { app: cvsm-api } ports: - port: 80 targetPort: 8080Ingress dengan cert-manager
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: cvsm-api namespace: cvsm annotations: cert-manager.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/proxy-body-size: "1m"spec: ingressClassName: nginx tls: - hosts: [vault.company.com] secretName: cvsm-tls rules: - host: vault.company.com http: paths: - path: / pathType: Prefix backend: service: name: cvsm-api port: { number: 80 }Run migrations
# Apply migration dari dalam podPOD=$(kubectl -n cvsm get pod -l app=postgres -o name | head -1)kubectl -n cvsm exec -i $POD -- psql -U cvsm -d cvsm < migrations/009_oauth.sqlAtau pakai Job sekali-pakai untuk migrations:
apiVersion: batch/v1kind: Jobmetadata: name: cvsm-migrate namespace: cvsmspec: template: spec: restartPolicy: OnFailure containers: - name: migrate image: postgres:16-alpine command: ["sh", "-c"] args: - | for f in /migrations/*.sql; do echo "Applying $f" psql $DATABASE_URL < $f done env: - name: DATABASE_URL valueFrom: { secretKeyRef: { name: cvsm-env, key: DATABASE_URL } } volumeMounts: - name: migrations mountPath: /migrations volumes: - name: migrations configMap: { name: cvsm-migrations }Scaling
Horizontal
apiVersion: autoscaling/v2kind: HorizontalPodAutoscalermetadata: name: cvsm-api namespace: cvsmspec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: cvsm-api minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: { type: Utilization, averageUtilization: 70 }Database
Managed database (Cloud SQL, RDS, Neon, Supabase) direkomendasikan untuk production. Set DATABASE_URL di secret → Pod otomatis konek.
Helm chart
Helm chart resmi coming v0.3. Sementara, pakai manifests manual di github.com/RenzyArmstrong/Calvery-Vault/tree/main/deploy/k8s.