ScuttleBot

feat: Kubernetes deployment manifests (#9) deploy/k8s/: - ergo-pvc.yaml — 1Gi ReadWriteOnce PVC for ircd.db - ergo-deployment.yaml — single replica, Recreate strategy (required for RWO), liveness + readiness probes on /v1/status - ergo-service.yaml — LoadBalancer for IRC :6667, ClusterIP for API :8089 - scuttlebot-configmap.yaml — non-secret config - scuttlebot-secret.yaml — example template (never commit real values) - scuttlebot-deployment.yaml — SCUTTLEBOT_ERGO_EXTERNAL=true, all config from ConfigMap + Secret - scuttlebot-service.yaml — ClusterIP for REST :8080 and MCP :8081 - README.md — deploy steps, architecture diagram, secrets management options Postgres is external — document the requirement, do not manage it. Ergo is single-replica by design — HA via fast restart, not scale-out. Closes #9

lmata 2026-03-31 06:36 trunk
Commit 7bbcd816092f74fedfcaea917c9081024f268bed579d75ccb5caa18e44f9dd09
--- a/deploy/k8s/README.md
+++ b/deploy/k8s/README.md
@@ -0,0 +1,97 @@
1
+# Kubernetes deployment
2
+
3
+Production-grade deployment for scuttlebot on Kubernetes.
4
+
5
+## Architecture
6
+
7
+```
8
+ LoadBalancer
9
+ :6667 (IRC)
10
+
11
+ ┌────────────▼────────────┐
12
+ │ ergo │
13
+ │ (single replica) │
14
+ │ ircd.db on PVC │
15
+ └────────────┬────────────┘
16
+ │ ClusterIP :8089
17
+ ┌────────────▼────────────┐
18
+ │ scuttlebot │
19
+ │ REST API :8080 (CIP) │
20
+ │ MCP :8081 (CIP) │
21
+ └────────────┬────────────┘
22
+
23
+ ┌────────────▼────────────┐
24
+ │ Postgres │
25
+ │ (external, PaaS) │
26
+ └─────────────────────────┘
27
+```
28
+
29
+**Ergo is single-instance.** HA = fast pod restart with durable PVC, not horizontal scaling. `strategy: Recreate` is required — Ergo cannot run two pods sharing one `ReadWriteOnce` volume.
30
+
31
+**Postgres is external.** Use your cloud provider's managed Postgres (RDS, Cloud SQL, etc.). Scuttlebot expects a `postgres-dsn` secret.
32
+
33
+## Prerequisites
34
+
35
+- A running Kubernetes cluster
36
+- `kubectl` configured
37
+- A Postgres instance reachable from the cluster
38
+- Container images built and pushed (see below)
39
+
40
+## Deploying
41
+
42
+### 1. Build and push images
43
+
44
+```sh
45
+# scuttlebot
46
+docker build -f deploy/docker/Dockerfile -t ghcr.io/conflicthq/scuttlebot:latest .
47
+docker push ghcr.io/conflicthq/scuttlebot:latest
48
+
49
+# ergo (custom image with envsubst)
50
+docker build -f deploy/compose/ergo/Dockerfile -t ghcr.io/conflicthq/scuttlebot-ergo:latest deploy/compose/ergo/
51
+docker push ghcr.io/conflicthq/scuttlebot-ergo:latest
52
+```
53
+
54
+### 2. Create the secret
55
+
56
+```sh
57
+kubectl create secret generic scuttlebot-secrets \
58
+ --from-literal=ergo-api-token=$(openssl rand -hex 32) \
59
+ --from-literal=postgres-dsn='postgres://scuttlebot:PASSWORD@HOST:5432/scuttlebot?sslmode=require'
60
+```
61
+
62
+Do **not** commit `scuttlebot-secret.yaml` with real values. The file in this directory is an example template only.
63
+
64
+### 3. Apply manifests
65
+
66
+```sh
67
+kubectl apply -f deploy/k8s/
68
+```
69
+
70
+### 4. Watch rollout
71
+
72
+```sh
73
+kubectl rollout status deployment/ergo
74
+kubectl rollout status deployment/scuttlebot
75
+```
76
+
77
+### 5. Get the API token
78
+
79
+```sh
80
+kubectl logs deployment/scuttlebot | grep "api token"
81
+```
82
+
83
+## Customising
84
+
85
+| What | How |
86
+|------|-----|
87
+| IRC network name / server name | Edit `scuttlebot-configmap.yaml` |
88
+| Storage class for Ergo PVC | Uncomment `storageClassName` in `ergo-pvc.yaml` |
89
+| Expose REST API externally | Change `scuttlebot-api` service type to `LoadBalancer` or add an Ingress |
90
+| Namespace | Add `namespace:` to all resource metadata |
91
+
92
+## Secrets management
93
+
94
+The example uses a plain Kubernetes Secret for simplicity. For production, prefer:
95
+- [Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets)
96
+- [External Secrets Operator](https://external-secrets.io/)
97
+- [HashiCorp Vault](https://www.vaultproject.io/)
--- a/deploy/k8s/README.md
+++ b/deploy/k8s/README.md
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/deploy/k8s/README.md
+++ b/deploy/k8s/README.md
@@ -0,0 +1,97 @@
1 # Kubernetes deployment
2
3 Production-grade deployment for scuttlebot on Kubernetes.
4
5 ## Architecture
6
7 ```
8 LoadBalancer
9 :6667 (IRC)
10
11 ┌────────────▼────────────┐
12 │ ergo │
13 │ (single replica) │
14 │ ircd.db on PVC │
15 └────────────┬────────────┘
16 │ ClusterIP :8089
17 ┌────────────▼────────────┐
18 │ scuttlebot │
19 │ REST API :8080 (CIP) │
20 │ MCP :8081 (CIP) │
21 └────────────┬────────────┘
22
23 ┌────────────▼────────────┐
24 │ Postgres │
25 │ (external, PaaS) │
26 └─────────────────────────┘
27 ```
28
29 **Ergo is single-instance.** HA = fast pod restart with durable PVC, not horizontal scaling. `strategy: Recreate` is required — Ergo cannot run two pods sharing one `ReadWriteOnce` volume.
30
31 **Postgres is external.** Use your cloud provider's managed Postgres (RDS, Cloud SQL, etc.). Scuttlebot expects a `postgres-dsn` secret.
32
33 ## Prerequisites
34
35 - A running Kubernetes cluster
36 - `kubectl` configured
37 - A Postgres instance reachable from the cluster
38 - Container images built and pushed (see below)
39
40 ## Deploying
41
42 ### 1. Build and push images
43
44 ```sh
45 # scuttlebot
46 docker build -f deploy/docker/Dockerfile -t ghcr.io/conflicthq/scuttlebot:latest .
47 docker push ghcr.io/conflicthq/scuttlebot:latest
48
49 # ergo (custom image with envsubst)
50 docker build -f deploy/compose/ergo/Dockerfile -t ghcr.io/conflicthq/scuttlebot-ergo:latest deploy/compose/ergo/
51 docker push ghcr.io/conflicthq/scuttlebot-ergo:latest
52 ```
53
54 ### 2. Create the secret
55
56 ```sh
57 kubectl create secret generic scuttlebot-secrets \
58 --from-literal=ergo-api-token=$(openssl rand -hex 32) \
59 --from-literal=postgres-dsn='postgres://scuttlebot:PASSWORD@HOST:5432/scuttlebot?sslmode=require'
60 ```
61
62 Do **not** commit `scuttlebot-secret.yaml` with real values. The file in this directory is an example template only.
63
64 ### 3. Apply manifests
65
66 ```sh
67 kubectl apply -f deploy/k8s/
68 ```
69
70 ### 4. Watch rollout
71
72 ```sh
73 kubectl rollout status deployment/ergo
74 kubectl rollout status deployment/scuttlebot
75 ```
76
77 ### 5. Get the API token
78
79 ```sh
80 kubectl logs deployment/scuttlebot | grep "api token"
81 ```
82
83 ## Customising
84
85 | What | How |
86 |------|-----|
87 | IRC network name / server name | Edit `scuttlebot-configmap.yaml` |
88 | Storage class for Ergo PVC | Uncomment `storageClassName` in `ergo-pvc.yaml` |
89 | Expose REST API externally | Change `scuttlebot-api` service type to `LoadBalancer` or add an Ingress |
90 | Namespace | Add `namespace:` to all resource metadata |
91
92 ## Secrets management
93
94 The example uses a plain Kubernetes Secret for simplicity. For production, prefer:
95 - [Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets)
96 - [External Secrets Operator](https://external-secrets.io/)
97 - [HashiCorp Vault](https://www.vaultproject.io/)
--- a/deploy/k8s/ergo-deployment.yaml
+++ b/deploy/k8s/ergo-deployment.yaml
@@ -0,0 +1,78 @@
1
+apiVersion: apps/v1
2
+kind: Deployment
3
+metadata:
4
+ name: ergo
5
+ labels:
6
+ app: ergo
7
+spec:
8
+ replicas: 1 # single replica — Ergo does not support horizontal scaling
9
+ strategy:
10
+ type: Recreate # required for ReadWriteOnce PVC — no rolling update
11
+ selector:
12
+ matchLabels:
13
+ app: ergo
14
+ template:
15
+ metadata:
16
+ labels:
17
+ app: ergo
18
+ spec:
19
+ containers:
20
+ - name: ergo
21
+ image: ghcr.io/conflicthq/scuttlebot-ergo:latest
22
+ imagePullPolicy: Always
23
+ ports:
24
+ - name: irc
25
+ containerPort: 6667
26
+ protocol: TCP
27
+ - name: api
28
+ containerPort: 8089
29
+ protocol: TCP
30
+ env:
31
+ - name: ERGO_NETWORK_NAME
32
+ valueFrom:
33
+ configMapKeyRef:
34
+ name: scuttlebot-config
35
+ key: ergo.network-name
36
+ - name: ERGO_SERVER_NAME
37
+ valueFrom:
38
+ configMapKeyRef:
39
+ name: scuttlebot-config
40
+ key: ergo.server-name
41
+ - name: ERGO_API_TOKEN
42
+ valueFrom:
43
+ secretKeyRef:
44
+ name: scuttlebot-secrets
45
+ key: ergo-api-token
46
+ - name: ERGO_HISTORY_ENABLED
47
+ value: "true"
48
+ - name: ERGO_HISTORY_DSN
49
+ valueFrom:
50
+ secretKeyRef:
51
+ name: scuttlebot-secrets
52
+ key: postgres-dsn
53
+ volumeMounts:
54
+ - name: ergo-data
55
+ mountPath: /ircd
56
+ livenessProbe:
57
+ httpGet:
58
+ path: /v1/status
59
+ port: 8089
60
+ httpHeaders:
61
+ - name: Authorization
62
+ value: "Bearer $(ERGO_API_TOKEN)"
63
+ initialDelaySeconds: 15
64
+ periodSeconds: 10
65
+ failureThreshold: 3
66
+ readinessProbe:
67
+ httpGet:
68
+ path: /v1/status
69
+ port: 8089
70
+ httpHeaders:
71
+ - name: Authorization
72
+ value: "Bearer $(ERGO_API_TOKEN)"
73
+ initialDelaySeconds: 5
74
+ periodSeconds: 5
75
+ volumes:
76
+ - name: ergo-data
77
+ persistentVolumeClaim:
78
+ claimName: ergo-data
--- a/deploy/k8s/ergo-deployment.yaml
+++ b/deploy/k8s/ergo-deployment.yaml
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/deploy/k8s/ergo-deployment.yaml
+++ b/deploy/k8s/ergo-deployment.yaml
@@ -0,0 +1,78 @@
1 apiVersion: apps/v1
2 kind: Deployment
3 metadata:
4 name: ergo
5 labels:
6 app: ergo
7 spec:
8 replicas: 1 # single replica — Ergo does not support horizontal scaling
9 strategy:
10 type: Recreate # required for ReadWriteOnce PVC — no rolling update
11 selector:
12 matchLabels:
13 app: ergo
14 template:
15 metadata:
16 labels:
17 app: ergo
18 spec:
19 containers:
20 - name: ergo
21 image: ghcr.io/conflicthq/scuttlebot-ergo:latest
22 imagePullPolicy: Always
23 ports:
24 - name: irc
25 containerPort: 6667
26 protocol: TCP
27 - name: api
28 containerPort: 8089
29 protocol: TCP
30 env:
31 - name: ERGO_NETWORK_NAME
32 valueFrom:
33 configMapKeyRef:
34 name: scuttlebot-config
35 key: ergo.network-name
36 - name: ERGO_SERVER_NAME
37 valueFrom:
38 configMapKeyRef:
39 name: scuttlebot-config
40 key: ergo.server-name
41 - name: ERGO_API_TOKEN
42 valueFrom:
43 secretKeyRef:
44 name: scuttlebot-secrets
45 key: ergo-api-token
46 - name: ERGO_HISTORY_ENABLED
47 value: "true"
48 - name: ERGO_HISTORY_DSN
49 valueFrom:
50 secretKeyRef:
51 name: scuttlebot-secrets
52 key: postgres-dsn
53 volumeMounts:
54 - name: ergo-data
55 mountPath: /ircd
56 livenessProbe:
57 httpGet:
58 path: /v1/status
59 port: 8089
60 httpHeaders:
61 - name: Authorization
62 value: "Bearer $(ERGO_API_TOKEN)"
63 initialDelaySeconds: 15
64 periodSeconds: 10
65 failureThreshold: 3
66 readinessProbe:
67 httpGet:
68 path: /v1/status
69 port: 8089
70 httpHeaders:
71 - name: Authorization
72 value: "Bearer $(ERGO_API_TOKEN)"
73 initialDelaySeconds: 5
74 periodSeconds: 5
75 volumes:
76 - name: ergo-data
77 persistentVolumeClaim:
78 claimName: ergo-data
--- a/deploy/k8s/ergo-pvc.yaml
+++ b/deploy/k8s/ergo-pvc.yaml
@@ -0,0 +1,13 @@
1
+apiVersion: v1
2
+kind: PersistentVolumeClaim
3
+metadata:
4
+ name: ergo-data
5
+ labels:
6
+ app: ergo
7
+spec:
8
+ accessModes:
9
+ - ReadWriteOnce
10
+ resources:
11
+ requests:
12
+ storage: 1Gi
13
+ # storageClassName: standard # uncomment and set for your cluster
--- a/deploy/k8s/ergo-pvc.yaml
+++ b/deploy/k8s/ergo-pvc.yaml
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/deploy/k8s/ergo-pvc.yaml
+++ b/deploy/k8s/ergo-pvc.yaml
@@ -0,0 +1,13 @@
1 apiVersion: v1
2 kind: PersistentVolumeClaim
3 metadata:
4 name: ergo-data
5 labels:
6 app: ergo
7 spec:
8 accessModes:
9 - ReadWriteOnce
10 resources:
11 requests:
12 storage: 1Gi
13 # storageClassName: standard # uncomment and set for your cluster
--- a/deploy/k8s/ergo-service.yaml
+++ b/deploy/k8s/ergo-service.yaml
@@ -0,0 +1,34 @@
1
+---
2
+# LoadBalancer for IRC — externally reachable by agents.
3
+apiVersion: v1
4
+kind: Service
5
+metadata:
6
+ name: ergo-irc
7
+ labels:
8
+ app: ergo
9
+spec:
10
+ type: LoadBalancer
11
+ selector:
12
+ app: ergo
13
+ ports:
14
+ - name: irc
15
+ port: 6667
16
+ targetPort: 6667
17
+ protocol: TCP
18
+---
19
+# ClusterIP for the Ergo HTTP management API — internal only.
20
+apiVersion: v1
21
+kind: Service
22
+metadata:
23
+ name: ergo-api
24
+ labels:
25
+ app: ergo
26
+spec:
27
+ type: ClusterIP
28
+ selector:
29
+ app: ergo
30
+ ports:
31
+ - name: api
32
+ port: 8089
33
+ targetPort: 8089
34
+ protocol: TCP
--- a/deploy/k8s/ergo-service.yaml
+++ b/deploy/k8s/ergo-service.yaml
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/deploy/k8s/ergo-service.yaml
+++ b/deploy/k8s/ergo-service.yaml
@@ -0,0 +1,34 @@
1 ---
2 # LoadBalancer for IRC — externally reachable by agents.
3 apiVersion: v1
4 kind: Service
5 metadata:
6 name: ergo-irc
7 labels:
8 app: ergo
9 spec:
10 type: LoadBalancer
11 selector:
12 app: ergo
13 ports:
14 - name: irc
15 port: 6667
16 targetPort: 6667
17 protocol: TCP
18 ---
19 # ClusterIP for the Ergo HTTP management API — internal only.
20 apiVersion: v1
21 kind: Service
22 metadata:
23 name: ergo-api
24 labels:
25 app: ergo
26 spec:
27 type: ClusterIP
28 selector:
29 app: ergo
30 ports:
31 - name: api
32 port: 8089
33 targetPort: 8089
34 protocol: TCP
--- a/deploy/k8s/scuttlebot-configmap.yaml
+++ b/deploy/k8s/scuttlebot-configmap.yaml
@@ -0,0 +1,12 @@
1
+apiVersion: v1
2
+kind: ConfigMap
3
+metadata:
4
+ name: scuttlebot-config
5
+data:
6
+ ergo.network-name: "scuttlebot"
7
+ ergo.server-name: "irc.scuttlebot.local"
8
+ ergo.api-addr: "http://ergo-api:8089"
9
+ ergo.irc-addr: "ergo-irc:6667"
10
+ api.addr: ":8080"
11
+ mcp.addr: ":8081"
12
+ db.driver: "postgres"
--- a/deploy/k8s/scuttlebot-configmap.yaml
+++ b/deploy/k8s/scuttlebot-configmap.yaml
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
--- a/deploy/k8s/scuttlebot-configmap.yaml
+++ b/deploy/k8s/scuttlebot-configmap.yaml
@@ -0,0 +1,12 @@
1 apiVersion: v1
2 kind: ConfigMap
3 metadata:
4 name: scuttlebot-config
5 data:
6 ergo.network-name: "scuttlebot"
7 ergo.server-name: "irc.scuttlebot.local"
8 ergo.api-addr: "http://ergo-api:8089"
9 ergo.irc-addr: "ergo-irc:6667"
10 api.addr: ":8080"
11 mcp.addr: ":8081"
12 db.driver: "postgres"
--- a/deploy/k8s/scuttlebot-deployment.yaml
+++ b/deploy/k8s/scuttlebot-deployment.yaml
@@ -0,0 +1,92 @@
1
+apiVersion: apps/v1
2
+kind: Deployment
3
+metadata:
4
+ name: scuttlebot
5
+ labels:
6
+ app: scuttlebot
7
+spec:
8
+ replicas: 1
9
+ selector:
10
+ matchLabels:
11
+ app: scuttlebot
12
+ template:
13
+ metadata:
14
+ labels:
15
+ app: scuttlebot
16
+ spec:
17
+ containers:
18
+ - name: scuttlebot
19
+ image: ghcr.io/conflicthq/scuttlebot:latest
20
+ imagePullPolicy: Always
21
+ ports:
22
+ - name: api
23
+ containerPort: 8080
24
+ - name: mcp
25
+ containerPort: 8081
26
+ env:
27
+ - name: SCUTTLEBOT_ERGO_EXTERNAL
28
+ value: "true"
29
+ - name: SCUTTLEBOT_ERGO_API_ADDR
30
+ valueFrom:
31
+ configMapKeyRef:
32
+ name: scuttlebot-config
33
+ key: ergo.api-addr
34
+ - name: SCUTTLEBOT_ERGO_IRC_ADDR
35
+ valueFrom:
36
+ configMapKeyRef:
37
+ name: scuttlebot-config
38
+ key: ergo.irc-addr
39
+ - name: SCUTTLEBOT_ERGO_NETWORK_NAME
40
+ valueFrom:
41
+ configMapKeyRef:
42
+ name: scuttlebot-config
43
+ key: ergo.network-name
44
+ - name: SCUTTLEBOT_ERGO_SERVER_NAME
45
+ valueFrom:
46
+ configMapKeyRef:
47
+ name: scuttlebot-config
48
+ key: ergo.server-name
49
+ - name: SCUTTLEBOT_ERGO_API_TOKEN
50
+ valueFrom:
51
+ secretKeyRef:
52
+ name: scuttlebot-secrets
53
+ key: ergo-api-token
54
+ - name: SCUTTLEBOT_DB_DRIVER
55
+ valueFrom:
56
+ configMapKeyRef:
57
+ name: scuttlebot-config
58
+ key: db.driver
59
+ - name: SCUTTLEBOT_DB_DSN
60
+ valueFrom:
61
+ secretKeyRef:
62
+ name: scuttlebot-secrets
63
+ key: postgres-dsn
64
+ - name: SCUTTLEBOT_API_ADDR
65
+ valueFrom:
66
+ configMapKeyRef:
67
+ name: scuttlebot-config
68
+ key: api.addr
69
+ - name: SCUTTLEBOT_MCP_ADDR
70
+ valueFrom:
71
+ configMapKeyRef:
72
+ name: scuttlebot-config
73
+ key: mcp.addr
74
+ livenessProbe:
75
+ httpGet:
76
+ path: /v1/status
77
+ port: 8080
78
+ httpHeaders:
79
+ - name: Authorization
80
+ value: "Bearer probe-check"
81
+ initialDelaySeconds: 20
82
+ periodSeconds: 15
83
+ failureThreshold: 3
84
+ readinessProbe:
85
+ httpGet:
86
+ path: /v1/status
87
+ port: 8080
88
+ httpHeaders:
89
+ - name: Authorization
90
+ value: "Bearer probe-check"
91
+ initialDelaySeconds: 10
92
+ periodSeconds: 10
--- a/deploy/k8s/scuttlebot-deployment.yaml
+++ b/deploy/k8s/scuttlebot-deployment.yaml
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/deploy/k8s/scuttlebot-deployment.yaml
+++ b/deploy/k8s/scuttlebot-deployment.yaml
@@ -0,0 +1,92 @@
1 apiVersion: apps/v1
2 kind: Deployment
3 metadata:
4 name: scuttlebot
5 labels:
6 app: scuttlebot
7 spec:
8 replicas: 1
9 selector:
10 matchLabels:
11 app: scuttlebot
12 template:
13 metadata:
14 labels:
15 app: scuttlebot
16 spec:
17 containers:
18 - name: scuttlebot
19 image: ghcr.io/conflicthq/scuttlebot:latest
20 imagePullPolicy: Always
21 ports:
22 - name: api
23 containerPort: 8080
24 - name: mcp
25 containerPort: 8081
26 env:
27 - name: SCUTTLEBOT_ERGO_EXTERNAL
28 value: "true"
29 - name: SCUTTLEBOT_ERGO_API_ADDR
30 valueFrom:
31 configMapKeyRef:
32 name: scuttlebot-config
33 key: ergo.api-addr
34 - name: SCUTTLEBOT_ERGO_IRC_ADDR
35 valueFrom:
36 configMapKeyRef:
37 name: scuttlebot-config
38 key: ergo.irc-addr
39 - name: SCUTTLEBOT_ERGO_NETWORK_NAME
40 valueFrom:
41 configMapKeyRef:
42 name: scuttlebot-config
43 key: ergo.network-name
44 - name: SCUTTLEBOT_ERGO_SERVER_NAME
45 valueFrom:
46 configMapKeyRef:
47 name: scuttlebot-config
48 key: ergo.server-name
49 - name: SCUTTLEBOT_ERGO_API_TOKEN
50 valueFrom:
51 secretKeyRef:
52 name: scuttlebot-secrets
53 key: ergo-api-token
54 - name: SCUTTLEBOT_DB_DRIVER
55 valueFrom:
56 configMapKeyRef:
57 name: scuttlebot-config
58 key: db.driver
59 - name: SCUTTLEBOT_DB_DSN
60 valueFrom:
61 secretKeyRef:
62 name: scuttlebot-secrets
63 key: postgres-dsn
64 - name: SCUTTLEBOT_API_ADDR
65 valueFrom:
66 configMapKeyRef:
67 name: scuttlebot-config
68 key: api.addr
69 - name: SCUTTLEBOT_MCP_ADDR
70 valueFrom:
71 configMapKeyRef:
72 name: scuttlebot-config
73 key: mcp.addr
74 livenessProbe:
75 httpGet:
76 path: /v1/status
77 port: 8080
78 httpHeaders:
79 - name: Authorization
80 value: "Bearer probe-check"
81 initialDelaySeconds: 20
82 periodSeconds: 15
83 failureThreshold: 3
84 readinessProbe:
85 httpGet:
86 path: /v1/status
87 port: 8080
88 httpHeaders:
89 - name: Authorization
90 value: "Bearer probe-check"
91 initialDelaySeconds: 10
92 periodSeconds: 10
--- a/deploy/k8s/scuttlebot-secret.yaml
+++ b/deploy/k8s/scuttlebot-secret.yaml
@@ -0,0 +1,15 @@
1
+# EXAMPLE ONLY — do not commit real values.
2
+# Create this secret with:
3
+# kubectl create secret generic scuttlebot-secrets \
4
+# --from-literal=ergo-api-token=<your-token> \
5
+# --from-literal=postgres-dsn='postgres://user:pass@host/db?sslmode=require'
6
+#
7
+# Or use your preferred secrets manager (Vault, Sealed Secrets, ESO, etc.)
8
+apiVersion: v1
9
+kind: Secret
10
+metadata:
11
+ name: scuttlebot-secrets
12
+type: Opaque
13
+stringData:
14
+ ergo-api-token: "CHANGE_ME"
15
+ postgres-dsn: "postgres://scuttlebot:CHANGE_ME@postgres-host:5432/scuttlebot?sslmode=require"
--- a/deploy/k8s/scuttlebot-secret.yaml
+++ b/deploy/k8s/scuttlebot-secret.yaml
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/deploy/k8s/scuttlebot-secret.yaml
+++ b/deploy/k8s/scuttlebot-secret.yaml
@@ -0,0 +1,15 @@
1 # EXAMPLE ONLY — do not commit real values.
2 # Create this secret with:
3 # kubectl create secret generic scuttlebot-secrets \
4 # --from-literal=ergo-api-token=<your-token> \
5 # --from-literal=postgres-dsn='postgres://user:pass@host/db?sslmode=require'
6 #
7 # Or use your preferred secrets manager (Vault, Sealed Secrets, ESO, etc.)
8 apiVersion: v1
9 kind: Secret
10 metadata:
11 name: scuttlebot-secrets
12 type: Opaque
13 stringData:
14 ergo-api-token: "CHANGE_ME"
15 postgres-dsn: "postgres://scuttlebot:CHANGE_ME@postgres-host:5432/scuttlebot?sslmode=require"
--- a/deploy/k8s/scuttlebot-service.yaml
+++ b/deploy/k8s/scuttlebot-service.yaml
@@ -0,0 +1,33 @@
1
+---
2
+# ClusterIP for the REST API — internal access.
3
+# Expose externally via an Ingress or change type to LoadBalancer.
4
+apiVersion: v1
5
+kind: Service
6
+metadata:
7
+ name: scuttlebot-api
8
+ labels:
9
+ app: scuttlebot
10
+spec:
11
+ type: ClusterIP
12
+ selector:
13
+ app: scuttlebot
14
+ ports:
15
+ - name: api
16
+ port: 8080
17
+ targetPort: 8080
18
+---
19
+# ClusterIP for the MCP server — internal access for AI agent tooling.
20
+apiVersion: v1
21
+kind: Service
22
+metadata:
23
+ name: scuttlebot-mcp
24
+ labels:
25
+ app: scuttlebot
26
+spec:
27
+ type: ClusterIP
28
+ selector:
29
+ app: scuttlebot
30
+ ports:
31
+ - name: mcp
32
+ port: 8081
33
+ targetPort: 8081
--- a/deploy/k8s/scuttlebot-service.yaml
+++ b/deploy/k8s/scuttlebot-service.yaml
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/deploy/k8s/scuttlebot-service.yaml
+++ b/deploy/k8s/scuttlebot-service.yaml
@@ -0,0 +1,33 @@
1 ---
2 # ClusterIP for the REST API — internal access.
3 # Expose externally via an Ingress or change type to LoadBalancer.
4 apiVersion: v1
5 kind: Service
6 metadata:
7 name: scuttlebot-api
8 labels:
9 app: scuttlebot
10 spec:
11 type: ClusterIP
12 selector:
13 app: scuttlebot
14 ports:
15 - name: api
16 port: 8080
17 targetPort: 8080
18 ---
19 # ClusterIP for the MCP server — internal access for AI agent tooling.
20 apiVersion: v1
21 kind: Service
22 metadata:
23 name: scuttlebot-mcp
24 labels:
25 app: scuttlebot
26 spec:
27 type: ClusterIP
28 selector:
29 app: scuttlebot
30 ports:
31 - name: mcp
32 port: 8081
33 targetPort: 8081

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button