Draw Things is an on-device Stable Diffusion app for macOS and iOS. The official draw-things-grpc-server-cli container exposes the same inference pipeline behind a gRPC API, so the phone/Mac app can offload generation to a beefy GPU box.
This chart deploys that gRPC server on Kubernetes, paired with a persistent volume for model storage and an NVIDIA GPU request. Behaviour is driven by the bjw-s-labs common library, so all knobs live in values.yaml.
Key features:
nvidia.com/gpu requested by default/grpc-modelshelm repo add obeone https://charts.obeone.cloud
helm install draw-things obeone/draw-things
nvidia.com/gpu resources are schedulable). Depending on your runtime, you may also need to set defaultPodOptions.runtimeClassName: nvidia.helm install draw-things obeone/draw-things
The chart will:
Deployment with one replica (single-GPU singleton)./grpc-models.ClusterIP service on port 7859.To override common knobs:
helm install draw-things obeone/draw-things \
--set persistence.models.size=200Gi \
--set defaultPodOptions.runtimeClassName=nvidia
helm uninstall draw-things
The PVC is retained by default — delete it explicitly if you want a clean slate:
kubectl delete pvc -l app.kubernetes.io/name=draw-things
values.yamldefaultPodOptions:
runtimeClassName: nvidia
controllers:
main:
containers:
main:
resources:
limits:
nvidia.com/gpu: 1
requests:
nvidia.com/gpu: 1
persistence:
models:
enabled: true
size: 200Gi
accessMode: ReadWriteOnce
globalMounts:
- path: /grpc-models
service:
main:
ports:
grpc:
port: 7859
| Key | Type | Default | Description |
|---|---|---|---|
| controllers.main.containers.main.image.repository | string | drawthingsai/draw-things-grpc-server-cli |
Image repository |
| controllers.main.containers.main.image.tag | string | `` | Image tag (defaults to appVersion: latest) |
| controllers.main.containers.main.image.pullPolicy | string | IfNotPresent |
Image pull policy |
| controllers.main.containers.main.command | list | ["gRPCServerCLI"] |
Container command |
| controllers.main.containers.main.args | list | ["/grpc-models"] |
Container args |
| Key | Type | Default | Description |
|---|---|---|---|
| defaultPodOptions.runtimeClassName | string | unset | NVIDIA RuntimeClass name. Set to nvidia if your cluster needs explicit runtime opt-in. |
controllers.main.containers.main.resources.requests.nvidia.com/gpu |
int | 1 |
GPUs requested (must equal limits) |
controllers.main.containers.main.resources.limits.nvidia.com/gpu |
int | 1 |
GPUs allocated |
| Key | Type | Default | Description |
|---|---|---|---|
| service.main.type | string | ClusterIP |
Service type |
| service.main.ports.grpc.port | int | 7859 |
gRPC service port |
| service.main.ports.grpc.protocol | string | TCP |
Service port protocol |
| Key | Type | Default | Description |
|---|---|---|---|
| persistence.models.enabled | bool | true |
Enable PVC for /grpc-models |
| persistence.models.size | string | 50Gi |
PVC size |
| persistence.models.accessMode | string | ReadWriteOnce |
PVC access mode |
| persistence.models.globalMounts | list | [/grpc-models] |
Mount paths for the models volume |
| Key | Type | Default | Description |
|---|---|---|---|
| ingress.main.enabled | bool | false |
Enable ingress. gRPC requires end-to-end h2c support. |
| ingress.main.hosts | list | [] |
Ingress hosts |
| ingress.main.tls | list | [] |
Ingress TLS |
The container looks up checkpoints in /grpc-models. Three ways to populate it:
kubectl cp — fine for a quick test:
POD=$(kubectl get pod -l app.kubernetes.io/name=draw-things -o name | head -n1)
kubectl cp ./my-model.safetensors default/${POD#pod/}:/grpc-models/
Init container (downloader) — declare an extra container in controllers.main.initContainers that wgets checkpoints into /grpc-models at boot time.
Pre-populated PVC — point persistence.models.existingClaim at a PVC you already filled out-of-band (NFS share, restored snapshot, etc.).
kubectl port-forward svc/draw-things 7859:7859
Then in the macOS / iOS app, add a remote server pointing to 127.0.0.1:7859.
Pending — 0/N nodes are available: insufficient nvidia.com/gpuThe cluster has no schedulable GPU. Verify with:
kubectl get nodes -o json | jq '.items[].status.allocatable | with_entries(select(.key | contains("nvidia")))'
Install / fix the NVIDIA device plugin before continuing.
Check logs:
kubectl logs -l app.kubernetes.io/name=draw-things
A frequent cause is an empty /grpc-models directory — populate it (see above) or the server will refuse to start.
| Repository | Name | Version |
|---|---|---|
| https://bjw-s-labs.github.io/helm-charts | common | 5.0.1 |
| Name | Url | |
|---|---|---|
| obeone | obeone@obeone.org | Â |