📦
Bunty

Deploy to Kubernetes

Kubernetes (K8s) provides powerful orchestration for containerized Bunty applications, offering features like auto-scaling, rolling updates, and self-healing.

Prerequisites

  • Docker image of your Bunty application
  • Kubernetes cluster (local or cloud)
  • kubectl CLI installed

Quick Start

Basic Deployment

Create k8s/deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: bunty-app
  labels:
    app: bunty-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: bunty-app
  template:
    metadata:
      labels:
        app: bunty-app
    spec:
      containers:
      - name: bunty-app
        image: your-registry/bunty-app:latest
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        - name: PORT
          value: "3000"
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5

Service

Create k8s/service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: bunty-app-service
spec:
  selector:
    app: bunty-app
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000

Deploy

# Apply configurations
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml

# Check status
kubectl get deployments
kubectl get pods
kubectl get services

Complete Production Setup

1. Namespace

# k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: bunty-production

2. ConfigMap

# k8s/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: bunty-config
  namespace: bunty-production
data:
  NODE_ENV: "production"
  LOG_LEVEL: "info"
  PORT: "3000"

3. Secrets

# k8s/secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: bunty-secrets
  namespace: bunty-production
type: Opaque
data:
  database-url: <base64-encoded-value>
  redis-url: <base64-encoded-value>
  jwt-secret: <base64-encoded-value>

Create secrets:

# Create from literal
kubectl create secret generic bunty-secrets \
  --from-literal=database-url='postgresql://user:pass@host:5432/db' \
  --from-literal=jwt-secret='your-secret-key' \
  -n bunty-production

# Or from file
kubectl create secret generic bunty-secrets \
  --from-env-file=.env.production \
  -n bunty-production

4. Deployment with All Features

# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bunty-app
  namespace: bunty-production
  labels:
    app: bunty-app
    version: v1
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: bunty-app
  template:
    metadata:
      labels:
        app: bunty-app
        version: v1
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "3000"
        prometheus.io/path: "/metrics"
    spec:
      serviceAccountName: bunty-app
      containers:
      - name: bunty-app
        image: your-registry/bunty-app:1.0.0
        imagePullPolicy: Always
        ports:
        - name: http
          containerPort: 3000
          protocol: TCP
        env:
        - name: NODE_ENV
          valueFrom:
            configMapKeyRef:
              name: bunty-config
              key: NODE_ENV
        - name: PORT
          valueFrom:
            configMapKeyRef:
              name: bunty-config
              key: PORT
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: bunty-secrets
              key: database-url
        - name: REDIS_URL
          valueFrom:
            secretKeyRef:
              name: bunty-secrets
              key: redis-url
        - name: JWT_SECRET
          valueFrom:
            secretKeyRef:
              name: bunty-secrets
              key: jwt-secret
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "1000m"
        livenessProbe:
          httpGet:
            path: /health
            port: http
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /ready
            port: http
          initialDelaySeconds: 10
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 3
        startupProbe:
          httpGet:
            path: /health
            port: http
          initialDelaySeconds: 0
          periodSeconds: 10
          timeoutSeconds: 3
          failureThreshold: 30
        volumeMounts:
        - name: config
          mountPath: /app/config
          readOnly: true
      volumes:
      - name: config
        configMap:
          name: bunty-config
      imagePullSecrets:
      - name: registry-secret
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - bunty-app
              topologyKey: kubernetes.io/hostname

5. Horizontal Pod Autoscaler

# k8s/hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: bunty-app-hpa
  namespace: bunty-production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: bunty-app
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 50
        periodSeconds: 15
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
      - type: Percent
        value: 100
        periodSeconds: 15
      - type: Pods
        value: 2
        periodSeconds: 15
      selectPolicy: Max

6. Ingress

# k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: bunty-app-ingress
  namespace: bunty-production
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rate-limit: "100"
spec:
  tls:
  - hosts:
    - api.example.com
    secretName: bunty-tls
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: bunty-app-service
            port:
              number: 80

7. Service with Multiple Ports

# k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: bunty-app-service
  namespace: bunty-production
  labels:
    app: bunty-app
spec:
  type: ClusterIP
  selector:
    app: bunty-app
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 3000
  - name: metrics
    protocol: TCP
    port: 9090
    targetPort: 3000
  sessionAffinity: ClientIP

Database and Redis

PostgreSQL StatefulSet

# k8s/postgres.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
  namespace: bunty-production
spec:
  serviceName: postgres
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:16-alpine
        ports:
        - containerPort: 5432
        env:
        - name: POSTGRES_DB
          value: bunty
        - name: POSTGRES_USER
          value: bunty
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: bunty-secrets
              key: postgres-password
        volumeMounts:
        - name: postgres-storage
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
  - metadata:
      name: postgres-storage
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
  name: postgres
  namespace: bunty-production
spec:
  selector:
    app: postgres
  ports:
  - port: 5432
  clusterIP: None

Redis Deployment

# k8s/redis.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  namespace: bunty-production
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:7-alpine
        ports:
        - containerPort: 6379
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: bunty-production
spec:
  selector:
    app: redis
  ports:
  - port: 6379

Apply All Configurations

# Create namespace
kubectl apply -f k8s/namespace.yaml

# Create secrets and config
kubectl apply -f k8s/secret.yaml
kubectl apply -f k8s/configmap.yaml

# Deploy database and cache
kubectl apply -f k8s/postgres.yaml
kubectl apply -f k8s/redis.yaml

# Deploy application
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/hpa.yaml
kubectl apply -f k8s/ingress.yaml

# Or apply all at once
kubectl apply -f k8s/

Helm Chart

Create Helm Chart

helm create bunty-app

values.yaml

replicaCount: 3

image:
  repository: your-registry/bunty-app
  pullPolicy: IfNotPresent
  tag: "1.0.0"

service:
  type: ClusterIP
  port: 80
  targetPort: 3000

ingress:
  enabled: true
  className: "nginx"
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
  hosts:
    - host: api.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: bunty-tls
      hosts:
        - api.example.com

resources:
  limits:
    cpu: 1000m
    memory: 1Gi
  requests:
    cpu: 500m
    memory: 512Mi

autoscaling:
  enabled: true
  minReplicas: 3
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70
  targetMemoryUtilizationPercentage: 80

env:
  - name: NODE_ENV
    value: "production"
  - name: PORT
    value: "3000"

secrets:
  - name: DATABASE_URL
    value: "postgresql://user:pass@postgres:5432/bunty"
  - name: REDIS_URL
    value: "redis://redis:6379"

Install with Helm

# Install
helm install bunty-app ./bunty-app -n bunty-production

# Upgrade
helm upgrade bunty-app ./bunty-app -n bunty-production

# Rollback
helm rollback bunty-app -n bunty-production

Common Operations

Rolling Update

# Update image
kubectl set image deployment/bunty-app bunty-app=your-registry/bunty-app:2.0.0 -n bunty-production

# Check rollout status
kubectl rollout status deployment/bunty-app -n bunty-production

# Rollback
kubectl rollout undo deployment/bunty-app -n bunty-production

Scaling

# Manual scale
kubectl scale deployment bunty-app --replicas=5 -n bunty-production

# Check HPA status
kubectl get hpa -n bunty-production

Debugging

# View logs
kubectl logs -f deployment/bunty-app -n bunty-production

# Exec into pod
kubectl exec -it bunty-app-xxx -n bunty-production -- /bin/sh

# Port forward
kubectl port-forward deployment/bunty-app 3000:3000 -n bunty-production

# Describe pod
kubectl describe pod bunty-app-xxx -n bunty-production

Next Steps

Have questions? Join our Discord community
Found an issue? Edit this page on GitHub