Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions deploy-k8s/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Ignore real manifests (contain user-specific values and secrets)
*.yaml
!*-sample.yaml
81 changes: 81 additions & 0 deletions deploy-k8s/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# ZeroClaw OpenShift deployment

Deploy a minimal ZeroClaw agent on OpenShift with an external LLM
provider (Anthropic, OpenAI, or any OpenAI-compatible API).

## Prerequisites

- `oc` CLI authenticated to your OpenShift cluster
- Container image pushed to an accessible registry
- API key for your LLM provider

## Quick start

1. Copy the sample manifests to create your real ones:

```bash
for f in deploy-k8s/*-sample.yaml; do cp "$f" "${f/-sample/}"; done
```

1. Edit `secret.yaml` and replace `REPLACE_WITH_YOUR_API_KEY` with
your actual API key
1. Update the `image` field in `deployment.yaml` to point to your
registry (e.g., `ghcr.io/youruser/zeroclaw:latest`)
1. Update the `namespace` in all files if you want a different name
1. Optionally edit `configmap.yaml` to change the provider or model
1. Apply all manifests:

```bash
oc apply -f deploy-k8s/
```

The real `.yaml` files are gitignored so your secrets and
customizations stay local.

## Verification

Check that the pod is running and the route is accessible:

```bash
oc -n zeroclaw get pods
oc -n zeroclaw get route zeroclaw
```

Test the health endpoint:

```bash
ROUTE=$(oc -n zeroclaw get route zeroclaw -o jsonpath='{.spec.host}')
curl -sf "https://${ROUTE}/health"
```

Send a test message:

```bash
curl -X POST "https://${ROUTE}/webhook" \
-H "Content-Type: application/json" \
-d '{"message": "hello, what model are you?"}'
```

## Configuration

Edit `configmap.yaml` to change runtime settings:

| Setting | Field | Default |
| ------- | ----- | ------- |
| LLM provider | `default_provider` | `anthropic` |
| Model | `default_model` | `claude-sonnet-4-20250514` |
| Temperature | `default_temperature` | `0.7` |
| Autonomy level | `autonomy.level` | `supervised` |

After editing, re-apply and restart the pod:

```bash
oc apply -f deploy-k8s/configmap.yaml
oc -n zeroclaw rollout restart deployment zeroclaw
```

## Cleanup

```bash
oc delete namespace zeroclaw
```
27 changes: 27 additions & 0 deletions deploy-k8s/configmap-sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: zeroclaw-config
namespace: zeroclaw
labels:
app.kubernetes.io/name: zeroclaw
app.kubernetes.io/part-of: zeroclaw
data:
config.toml: |
workspace_dir = "/zeroclaw-data/workspace"
config_path = "/zeroclaw-data/.zeroclaw/config.toml"
api_key = ""
default_provider = "anthropic"
default_model = "claude-sonnet-4-20250514"
default_temperature = 0.7

[gateway]
port = 42617
host = "[::]"
allow_public_bind = true
require_pairing = false
web_dist_dir = "/zeroclaw-data/web/dist"

[autonomy]
level = "supervised"
auto_approve = ["file_read", "file_write", "file_edit", "memory_recall", "memory_store", "web_search_tool", "web_fetch", "calculator", "glob_search", "content_search", "image_info", "weather", "git_operations"]
88 changes: 88 additions & 0 deletions deploy-k8s/deployment-sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: zeroclaw
namespace: zeroclaw
labels:
app.kubernetes.io/name: zeroclaw
app.kubernetes.io/part-of: zeroclaw
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: zeroclaw
template:
metadata:
labels:
app.kubernetes.io/name: zeroclaw
app.kubernetes.io/part-of: zeroclaw
spec:
containers:
- name: zeroclaw
image: ghcr.io/zeroclaw-labs/zeroclaw:latest
args: ["daemon"]
ports:
- name: gateway
containerPort: 42617
protocol: TCP
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: zeroclaw-api-key
key: api-key
- name: LANG
value: "C.UTF-8"
- name: HOME
value: "/zeroclaw-data"
- name: ZEROCLAW_WORKSPACE
value: "/zeroclaw-data/workspace"
- name: ZEROCLAW_GATEWAY_PORT
value: "42617"
volumeMounts:
- name: state
mountPath: /zeroclaw-data/.zeroclaw
- name: config
mountPath: /zeroclaw-data/.zeroclaw/config.toml
subPath: config.toml
readOnly: true
- name: workspace
mountPath: /zeroclaw-data/workspace
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "2"
livenessProbe:
httpGet:
path: /health
port: gateway
initialDelaySeconds: 10
periodSeconds: 60
timeoutSeconds: 10
readinessProbe:
httpGet:
path: /health
port: gateway
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
volumes:
- name: config
configMap:
name: zeroclaw-config
- name: state
emptyDir: {}
- name: workspace
emptyDir: {}
7 changes: 7 additions & 0 deletions deploy-k8s/namespace-sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: zeroclaw
labels:
app.kubernetes.io/name: zeroclaw
app.kubernetes.io/part-of: zeroclaw
18 changes: 18 additions & 0 deletions deploy-k8s/route-sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: zeroclaw
namespace: zeroclaw
labels:
app.kubernetes.io/name: zeroclaw
app.kubernetes.io/part-of: zeroclaw
spec:
to:
kind: Service
name: zeroclaw
weight: 100
port:
targetPort: gateway
tls:
termination: edge
insecureEdgeTerminationPolicy: Redirect
11 changes: 11 additions & 0 deletions deploy-k8s/secret-sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: zeroclaw-api-key
namespace: zeroclaw
labels:
app.kubernetes.io/name: zeroclaw
app.kubernetes.io/part-of: zeroclaw
type: Opaque
stringData:
api-key: "REPLACE_WITH_YOUR_API_KEY"
17 changes: 17 additions & 0 deletions deploy-k8s/service-sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: zeroclaw
namespace: zeroclaw
labels:
app.kubernetes.io/name: zeroclaw
app.kubernetes.io/part-of: zeroclaw
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: zeroclaw
ports:
- name: gateway
port: 42617
targetPort: gateway
protocol: TCP
Loading