Skip to main content

Deploy SkillFlaw to Kubernetes for development

Use this deployment shape when your cluster must expose the full SkillFlaw editor experience for developers, testers, or internal users.

This guide intentionally follows the current project deployment contract instead of an external Helm chart:

  • backend image: ghcr.io/cwinux/skillflaw_backend:latest
  • frontend image: ghcr.io/cwinux/skillflaw_frontend:latest
  • optional docs image: ghcr.io/cwinux/skillflaw_docs:latest
  • stateful dependencies: PostgreSQL and Redis

When to use this topology

Choose the development topology when you need all of the following in the same environment:

  • the browser editor and management UI
  • the backend API
  • shared state for collaborative internal testing
  • optional access to the standalone docs site for documentation review

For purely programmatic serving, skip the frontend and use the production guide instead.

Prerequisites

  • a Kubernetes cluster
  • kubectl
  • access to pull images from ghcr.io
  • a plan for PostgreSQL and Redis, either in-cluster or managed externally
  • a writable persistent volume for SKILLFLAW_CONFIG_DIR

For internal development or UAT, the simplest cluster layout is:

  • backend service on port 7860
  • frontend service on port 80
  • docs service on port 80 only if you want docs on a separate host or service
  • postgresql service
  • redis service

The frontend image serves only the application UI. If this environment needs public or shared docs access, deploy the docs image as its own service.

1. Create namespace, config, and secrets

The reference compose file already shows the minimum environment contract. Mirror that contract in Kubernetes instead of inventing a second configuration model.


_29
apiVersion: v1
_29
kind: Namespace
_29
metadata:
_29
name: skillflaw
_29
---
_29
apiVersion: v1
_29
kind: ConfigMap
_29
metadata:
_29
name: skillflaw-backend-config
_29
namespace: skillflaw
_29
data:
_29
SKILLFLAW_CONFIG_DIR: /var/lib/skillflaw
_29
SKILLFLAW_DATABASE_URL: postgresql://skillflaw:skillflaw@postgresql:5432/skillflaw
_29
SKILLFLAW_CONFIG_MODEL: local
_29
SKILLFLAW_CACHE_TYPE: redis
_29
SKILLFLAW_REDIS_HOST: redis
_29
SKILLFLAW_REDIS_PORT: "6379"
_29
SKILLFLAW_HOST: 0.0.0.0
_29
SKILLFLAW_PORT: "7860"
_29
SKILLFLAW_OPEN_BROWSER: "false"
_29
---
_29
apiVersion: v1
_29
kind: Secret
_29
metadata:
_29
name: skillflaw-runtime-secrets
_29
namespace: skillflaw
_29
type: Opaque
_29
stringData:
_29
skillflaw_secret_key: replace-with-your-secret-key-file-content

Mount the secret as a file and keep SKILLFLAW_SECRET_KEY_FILE pointed at that file path.

2. Provision PostgreSQL and Redis

For short-lived local cluster experiments, in-cluster PostgreSQL and Redis are acceptable.

For any shared internal environment, prefer:

  • persistent PostgreSQL storage
  • a clear backup policy
  • a Redis deployment with predictable memory limits

You can use in-cluster charts, an operator, or managed services. The important part is that the backend still receives the same connection values shown above.

3. Deploy the backend

The backend image exposes port 7860 and health checks at /health.


_61
apiVersion: apps/v1
_61
kind: Deployment
_61
metadata:
_61
name: skillflaw-backend
_61
namespace: skillflaw
_61
spec:
_61
replicas: 1
_61
selector:
_61
matchLabels:
_61
app: skillflaw-backend
_61
template:
_61
metadata:
_61
labels:
_61
app: skillflaw-backend
_61
spec:
_61
containers:
_61
- name: backend
_61
image: ghcr.io/cwinux/skillflaw_backend:latest
_61
ports:
_61
- containerPort: 7860
_61
envFrom:
_61
- configMapRef:
_61
name: skillflaw-backend-config
_61
env:
_61
- name: SKILLFLAW_SECRET_KEY_FILE
_61
value: /run/secrets/skillflaw_secret_key
_61
volumeMounts:
_61
- name: skillflaw-data
_61
mountPath: /var/lib/skillflaw
_61
- name: skillflaw-secret
_61
mountPath: /run/secrets/skillflaw_secret_key
_61
subPath: skillflaw_secret_key
_61
readOnly: true
_61
readinessProbe:
_61
httpGet:
_61
path: /health
_61
port: 7860
_61
livenessProbe:
_61
httpGet:
_61
path: /health
_61
port: 7860
_61
volumes:
_61
- name: skillflaw-data
_61
persistentVolumeClaim:
_61
claimName: skillflaw-backend-data
_61
- name: skillflaw-secret
_61
secret:
_61
secretName: skillflaw-runtime-secrets
_61
---
_61
apiVersion: v1
_61
kind: Service
_61
metadata:
_61
name: skillflaw-backend
_61
namespace: skillflaw
_61
spec:
_61
selector:
_61
app: skillflaw-backend
_61
ports:
_61
- name: http
_61
port: 7860
_61
targetPort: 7860

4. Deploy the frontend

The frontend expects BACKEND_URL and serves the application UI. In development-oriented clusters, this is usually the main entry point for users.


_36
apiVersion: apps/v1
_36
kind: Deployment
_36
metadata:
_36
name: skillflaw-frontend
_36
namespace: skillflaw
_36
spec:
_36
replicas: 1
_36
selector:
_36
matchLabels:
_36
app: skillflaw-frontend
_36
template:
_36
metadata:
_36
labels:
_36
app: skillflaw-frontend
_36
spec:
_36
containers:
_36
- name: frontend
_36
image: ghcr.io/cwinux/skillflaw_frontend:latest
_36
env:
_36
- name: BACKEND_URL
_36
value: http://skillflaw-backend.skillflaw.svc.cluster.local:7860/
_36
ports:
_36
- containerPort: 80
_36
---
_36
apiVersion: v1
_36
kind: Service
_36
metadata:
_36
name: skillflaw-frontend
_36
namespace: skillflaw
_36
spec:
_36
selector:
_36
app: skillflaw-frontend
_36
ports:
_36
- name: http
_36
port: 80
_36
targetPort: 80

5. Optional: deploy docs

If this environment needs documentation access, deploy the docs image as its own service and expose it on a dedicated docs hostname.


_33
apiVersion: apps/v1
_33
kind: Deployment
_33
metadata:
_33
name: skillflaw-docs
_33
namespace: skillflaw
_33
spec:
_33
replicas: 1
_33
selector:
_33
matchLabels:
_33
app: skillflaw-docs
_33
template:
_33
metadata:
_33
labels:
_33
app: skillflaw-docs
_33
spec:
_33
containers:
_33
- name: docs
_33
image: ghcr.io/cwinux/skillflaw_docs:latest
_33
ports:
_33
- containerPort: 80
_33
---
_33
apiVersion: v1
_33
kind: Service
_33
metadata:
_33
name: skillflaw-docs
_33
namespace: skillflaw
_33
spec:
_33
selector:
_33
app: skillflaw-docs
_33
ports:
_33
- name: http
_33
port: 80
_33
targetPort: 80

6. Expose services with ingress or port-forwarding

For quick validation, port-forward both services:

  • skillflaw-backend7860
  • skillflaw-frontend8080 or another local port

For shared environments, configure ingress rules such as:

  • app.example.comskillflaw-frontend
  • api.example.comskillflaw-backend
  • docs.example.comskillflaw-docs if docs are enabled

7. Validate the deployment

After rollout, verify the following:

  1. backend health check returns 200 at /health
  2. the UI loads from the frontend service
  3. the docs hostname loads if docs are enabled
  4. the editor can trigger a real flow run through the backend

Practical notes

  • keep backend replicas at 1 unless PostgreSQL, Redis, and shared storage are all ready for multi-instance use
  • treat development Kubernetes as a shared internal environment, not as a shortcut around configuration discipline
  • if you are deploying from source instead of images, remember that the backend serves built frontend assets from src/backend/base/skillflaw/frontend

See also