Kubernetes Deployment
Deploy Imagor Studio on Kubernetes for production-scale deployments.
Prerequisites
- Kubernetes cluster (1.19+)
- kubectl configured
- PostgreSQL database (recommended)
- S3-compatible storage (optional)
Basic Deployment
Namespace
apiVersion: v1
kind: Namespace
metadata:
name: imagor-studio
Database Secret
apiVersion: v1
kind: Secret
metadata:
name: database-secret
namespace: imagor-studio
type: Opaque
stringData:
url: postgres://user:password@postgres:5432/imagor_studio
Migration Job
apiVersion: batch/v1
kind: Job
metadata:
name: imagor-studio-migrate
namespace: imagor-studio
spec:
template:
spec:
containers:
- name: migrate
image: shumc/imagor-studio:latest
command: ["imagor-studio-migrate", "--migrate-command=up"]
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secret
key: url
restartPolicy: OnFailure
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: imagor-studio
namespace: imagor-studio
spec:
replicas: 3
selector:
matchLabels:
app: imagor-studio
template:
metadata:
labels:
app: imagor-studio
spec:
containers:
- name: imagor-studio
image: shumc/imagor-studio:latest
ports:
- containerPort: 8000
name: http
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: database-secret
key: url
- name: PORT
value: "8000"
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "2000m"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
Service
apiVersion: v1
kind: Service
metadata:
name: imagor-studio
namespace: imagor-studio
spec:
selector:
app: imagor-studio
ports:
- port: 80
targetPort: 8000
name: http
type: ClusterIP
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: imagor-studio
namespace: imagor-studio
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- imagor.example.com
secretName: imagor-studio-tls
rules:
- host: imagor.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: imagor-studio
port:
number: 80
Deploy
# Create namespace
kubectl apply -f namespace.yaml
# Create secrets
kubectl apply -f secrets.yaml
# Run migrations
kubectl apply -f migration-job.yaml
kubectl wait --for=condition=complete job/imagor-studio-migrate -n imagor-studio
# Deploy application
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
With PostgreSQL
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
namespace: imagor-studio
spec:
serviceName: postgres
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB
value: imagor_studio
- name: POSTGRES_USER
value: imagor
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: password
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: postgres-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
Scaling
Horizontal Pod Autoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: imagor-studio
namespace: imagor-studio
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: imagor-studio
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
Monitoring
ServiceMonitor (Prometheus)
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: imagor-studio
namespace: imagor-studio
spec:
selector:
matchLabels:
app: imagor-studio
endpoints:
- port: http
path: /metrics
interval: 30s
Best Practices
- Use StatefulSets for databases
- Configure resource limits
- Set up health checks
- Use secrets for sensitive data
- Enable autoscaling
- Configure ingress with TLS
- Set up monitoring and logging
- Use persistent volumes for data
Next Steps
- Migration Guide - Database migrations
- Configuration - Configure settings
- Security - Security best practices