CI/CD
Kubernetes
Run handoff run inside a Kubernetes pod with the token delivered as a Secret.
On Kubernetes, the image builds exactly like the Docker example. The difference is where the token comes from: a Secret resource instead of a runtime -e flag.
1. Create a Secret for the token
apiVersion: v1
kind: Secret
metadata:
name: handoff-token
namespace: myapp
type: Opaque
stringData:
HANDOFF_TOKEN: hnd_xxxxxxxxxxxxxxxxApply it:
kubectl apply -f handoff-token.yamlOr create directly:
kubectl create secret generic handoff-token \
--namespace myapp \
--from-literal=HANDOFF_TOKEN=hnd_xxxxxxxx2. Reference it from the Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: myapp
spec:
replicas: 3
selector:
matchLabels: { app: myapp }
template:
metadata:
labels: { app: myapp }
spec:
containers:
- name: app
image: registry.example.com/myapp:latest
envFrom:
- secretRef:
name: handoff-token
command:
- handoff
- run
- --project
- myapp
- --env
- production
- --
- bun
- run
- dist/server.js
ports:
- containerPort: 3000
resources:
limits: { cpu: '1', memory: 512Mi }
livenessProbe:
httpGet: { path: /healthz, port: 3000 }
initialDelaySeconds: 15envFrom.secretRef injects HANDOFF_TOKEN into the container's env. handoff run reads it, pulls the rest of your variables in memory, and execs your app.
Rotating the token
Update the Secret, then roll the Deployment so pods restart and read the new token:
kubectl create secret generic handoff-token \
--namespace myapp \
--from-literal=HANDOFF_TOKEN=hnd_newxxxx \
--dry-run=client -o yaml | kubectl apply -f -
kubectl rollout restart deployment/myapp -n myappRotating a Handoff variable
Update the value in the dashboard, then roll the Deployment the same way. Pods restart, handoff run pulls fresh values on each startup.
kubectl rollout restart deployment/myapp -n myappAlternatives
- External Secrets Operator: if you already run ESO with Vault or AWS Secrets Manager as the backend, skip
handoff runat runtime and sync from Handoff to your backend in CI instead. See the serverless pattern. - Init container + emptyDir: not recommended. Writing pulled values to a shared volume re-introduces disk-level exposure and loses the "never written to disk" property that makes
handoff runvaluable.