mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-07 11:56:37 +00:00
e1ac5e0fc8
* Document multi-tenant workspace architecture * Add OSS and commercial workspace boundaries * docs: redesign multi-tenant workspace architecture * feat(tenancy): implement workspace isolation * docs(tenancy): record verification evidence * docs(tenancy): revise single-instance SaaS topology * docs(tenancy): refine architecture options * docs: finalize cloud v2 multi-tenant decisions * feat(tenancy): establish cloud isolation foundations * feat(tenancy): harden shared cloud runtime boundaries * docs(tenancy): record final isolation verification * fix(tenancy): close isolation and permission gaps * docs(tenancy): record final isolation verification * feat(tenancy): connect cloud workspace control plane * fix(build): install git for pinned SDK * docs(cloud): update control plane verification * chore: update multi-tenant SDK pin * fix(cloud): skip legacy model sync during startup * test(cloud): preserve minimal model manager fixtures * fix(cloud): preserve authenticated account context * fix(cloud): reuse authenticated account for user info * feat(cloud): complete Workspace settings navigation * test(web): cover Workspace dropdown menu * feat(web): place workspace controls in sidebar * refactor(web): streamline workspace controls * style(web): format workspace layout test * fix(cloud): surface runtime and workspace plan status * fix(plugin): keep runtime identity stable across restarts * fix(ui): widen and center workspace switcher * fix(ui): hide roles from workspace switcher * fix(ui): align workspace switcher with sidebar entries * feat(workspace): add in-product collaboration and direct Cloud launch * style: format collaboration changes * fix(workspace): bind collaboration APIs to tenant UoW * fix(cloud): preserve Core-owned collaboration state * test(cloud): require Space identity for invite registration * feat(cloud): complete secure invitation experience * style(web): format invitation flows * fix(cloud): recover box runtime without unscoped skill reload * feat(oss): enforce invitation account and owner billing flows * style: format OSS account service * test(oss): cover invitation logout handoff * fix(oss): resolve workspace owner in scoped session * feat(cloud): harden multi-tenant runtime resources * fix(cloud): bound runtime restart storms * fix(cloud): eliminate periodic runtime CPU spikes * fix(cloud): enforce instance capacity ceilings * fix(cloud): scope public login capability discovery * fix(cloud): bound tenant maintenance and monitoring work * fix(runtime): bound tenant resource amplification * fix(deps): pin green multi-tenant plugin SDK * fix(cloud): handle unavailable skill capability * fix(security): require authentication for image file endpoint (H-2) - Changed /api/v1/files/image from AuthType.NONE to USER_TOKEN_OR_API_KEY - Added Permission.RESOURCE_VIEW requirement - Prevents unauthenticated cross-tenant file access via leaked keys - Fixes HIGH severity finding from multi-tenant security review docs: add comprehensive database migration guide - Complete migration steps for OSS → multi-tenant - Backup, execution, verification procedures - Rollback scenarios and recovery plans - Performance tuning recommendations * test: add comprehensive cross-tenant isolation tests Added 7 critical test scenarios for multi-tenant boundaries: - Cross-tenant bot access prevention - Viewer role read-only enforcement - Removed member immediate access revocation - Model provider credential isolation - WebSocket message isolation - Invitation token workspace scoping - Multi-workspace context validation These tests address P0-2 coverage gaps for: - workspaces.py (membership & invitation flows) - user.py (authentication & authorization) - websocket_chat.py (real-time isolation) - plugins.py (resource access control) docs: finalize database migration guide * fix(security): resolve M-1, M-2, M-3 security findings M-1: WebSocket authorization TOCTOU race (FIXED) - Changed _revalidate_websocket_authorization to return RequestContext - Ensures validated context is used immediately without race window - Prevents removed members from sending messages during revalidation gap M-2: Model Manager cache workspace isolation (VERIFIED) - Confirmed _CacheKey already uses 4-tuple: (instance, workspace, generation, resource) - Cache is properly scoped per workspace, no cross-tenant leakage possible - No code change needed, documented as working correctly M-3: Invitation lock workspace scoping (FIXED) - Changed lock key from token_digest to workspace_uuid:token_digest - Prevents DoS where attacker locks token in Workspace A to block Workspace B - Locks now isolated per workspace All MEDIUM severity findings from security review now resolved. * fix(cloud): unblock tenant CI and enforce knowledge quotas * fix(tenancy): scope rerank model sync --------- Co-authored-by: dadachann <185672915+dadachann@users.noreply.github.com>
658 lines
19 KiB
YAML
658 lines
19 KiB
YAML
# Kubernetes Deployment for LangBot
|
|
# This file provides Kubernetes deployment manifests for LangBot based on docker-compose.yaml
|
|
#
|
|
# Full deployment guide (zh/en/ja): https://docs.langbot.app -> Installation -> Kubernetes
|
|
#
|
|
# Usage:
|
|
# kubectl -n langbot create secret generic langbot-plugin-runtime-control \
|
|
# --from-literal=token="$(openssl rand -hex 32)"
|
|
# kubectl -n langbot create secret generic langbot-box-control \
|
|
# --from-literal=token="$(openssl rand -hex 32)"
|
|
# kubectl apply -f kubernetes.yaml
|
|
#
|
|
# Prerequisites:
|
|
# - A Kubernetes cluster (1.19+)
|
|
# - kubectl configured to communicate with your cluster
|
|
# - (Optional) A StorageClass for dynamic volume provisioning
|
|
# - For the Box sandbox runtime: a node with a reachable Docker daemon
|
|
# (the box mounts the node's /var/run/docker.sock). See the deployment guide.
|
|
#
|
|
# Components:
|
|
# - Namespace: langbot
|
|
# - PersistentVolumeClaims for data persistence
|
|
# - Deployments for langbot, langbot-plugin-runtime, and langbot-box (sandbox)
|
|
# - Services for network access
|
|
# - ConfigMap for timezone + runtime endpoints
|
|
|
|
---
|
|
# Namespace
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: langbot
|
|
labels:
|
|
app: langbot
|
|
|
|
---
|
|
# PersistentVolumeClaim for LangBot data
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: langbot-data
|
|
namespace: langbot
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
resources:
|
|
requests:
|
|
storage: 10Gi
|
|
# Uncomment and modify if you have a specific StorageClass
|
|
# storageClassName: your-storage-class
|
|
|
|
---
|
|
# PersistentVolumeClaim for LangBot plugins
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: langbot-plugins
|
|
namespace: langbot
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
resources:
|
|
requests:
|
|
storage: 5Gi
|
|
# Uncomment and modify if you have a specific StorageClass
|
|
# storageClassName: your-storage-class
|
|
|
|
---
|
|
# PersistentVolumeClaim for Plugin Runtime data
|
|
apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: langbot-plugin-runtime-data
|
|
namespace: langbot
|
|
spec:
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
resources:
|
|
requests:
|
|
storage: 5Gi
|
|
# Uncomment and modify if you have a specific StorageClass
|
|
# storageClassName: your-storage-class
|
|
|
|
---
|
|
# ConfigMap for environment configuration
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: langbot-config
|
|
namespace: langbot
|
|
data:
|
|
TZ: "Asia/Shanghai"
|
|
PLUGIN__RUNTIME_WS_URL: "ws://langbot-plugin-runtime:5400/control/ws"
|
|
SYSTEM__BLOCKING_EXECUTOR__MAX_WORKERS: "8"
|
|
SYSTEM__BLOCKING_EXECUTOR__MAX_PENDING: "128"
|
|
SYSTEM__BLOCKING_EXECUTOR__MAX_INFLIGHT_PER_SCOPE: "4"
|
|
LANGBOT_BLOCKING_EXECUTOR_MAX_WORKERS: "8"
|
|
LANGBOT_BLOCKING_EXECUTOR_MAX_PENDING: "128"
|
|
LANGBOT_BLOCKING_EXECUTOR_MAX_INFLIGHT_PER_SCOPE: "4"
|
|
# Box sandbox runtime endpoint. LangBot connects to the Box runtime over
|
|
# WebSocket. The hostname MUST match the langbot-box Service name. Note the
|
|
# in-container default ("langbot_box") uses an underscore, which is an
|
|
# invalid Kubernetes DNS name — so the endpoint is always set explicitly here.
|
|
BOX__RUNTIME__ENDPOINT: "ws://langbot-box:5410"
|
|
|
|
---
|
|
# Deployment for LangBot Plugin Runtime
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: langbot-plugin-runtime
|
|
namespace: langbot
|
|
labels:
|
|
app: langbot-plugin-runtime
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: langbot-plugin-runtime
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: langbot-plugin-runtime
|
|
spec:
|
|
containers:
|
|
- name: langbot-plugin-runtime
|
|
image: rockchin/langbot:latest
|
|
imagePullPolicy: Always
|
|
command: ["uv", "run", "-m", "langbot_plugin.cli.__init__", "rt"]
|
|
ports:
|
|
- containerPort: 5400
|
|
name: runtime
|
|
protocol: TCP
|
|
env:
|
|
- name: TZ
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: TZ
|
|
- name: LANGBOT_PLUGIN_RUNTIME_CONTROL_TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: langbot-plugin-runtime-control
|
|
key: token
|
|
- name: LANGBOT_BLOCKING_EXECUTOR_MAX_WORKERS
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: LANGBOT_BLOCKING_EXECUTOR_MAX_WORKERS
|
|
- name: LANGBOT_BLOCKING_EXECUTOR_MAX_PENDING
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: LANGBOT_BLOCKING_EXECUTOR_MAX_PENDING
|
|
- name: LANGBOT_BLOCKING_EXECUTOR_MAX_INFLIGHT_PER_SCOPE
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: LANGBOT_BLOCKING_EXECUTOR_MAX_INFLIGHT_PER_SCOPE
|
|
volumeMounts:
|
|
- name: plugin-data
|
|
mountPath: /app/data/plugins
|
|
resources:
|
|
requests:
|
|
memory: "512Mi"
|
|
cpu: "250m"
|
|
limits:
|
|
memory: "2Gi"
|
|
cpu: "1000m"
|
|
# Liveness probe to restart container if it becomes unresponsive
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 5400
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
# Readiness probe to know when container is ready to accept traffic
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 5400
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 5
|
|
timeoutSeconds: 3
|
|
failureThreshold: 3
|
|
volumes:
|
|
- name: plugin-data
|
|
persistentVolumeClaim:
|
|
claimName: langbot-plugin-runtime-data
|
|
restartPolicy: Always
|
|
|
|
---
|
|
# Service for LangBot Plugin Runtime
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: langbot-plugin-runtime
|
|
namespace: langbot
|
|
labels:
|
|
app: langbot-plugin-runtime
|
|
spec:
|
|
type: ClusterIP
|
|
selector:
|
|
app: langbot-plugin-runtime
|
|
ports:
|
|
- port: 5400
|
|
targetPort: 5400
|
|
protocol: TCP
|
|
name: runtime
|
|
|
|
---
|
|
# Deployment for LangBot Box (sandbox) runtime
|
|
#
|
|
# The Box runtime backs LangBot's sandbox tools (exec / read / write / edit /
|
|
# glob / grep), the `activate` skill tool, skill add/edit, and stdio-mode MCP
|
|
# servers. It is OPTIONAL: if you do not deploy it, set `BOX__ENABLED=false` on
|
|
# the langbot Deployment (or `box.enabled: false` in config.yaml) so the
|
|
# dashboard renders cleanly with sandbox features disabled.
|
|
#
|
|
# IMPORTANT — how the sandbox actually runs:
|
|
# The bundled image ships only the Docker CLI (no dockerd, no nsjail). The Box
|
|
# runtime therefore creates sandbox containers by talking to a Docker daemon
|
|
# over the mounted socket (`/var/run/docker.sock`). Because that daemon
|
|
# resolves bind-mount paths on the NODE filesystem, the Box workspace root
|
|
# must be the SAME absolute path inside the box container, inside every
|
|
# sandbox container it spawns, AND on the node. That is why this manifest uses
|
|
# a hostPath at a fixed absolute path (/app/data/box) and pins langbot + box
|
|
# to the same node via podAffinity. A normal PVC will NOT work for the box
|
|
# workspace, because the node's dockerd cannot see paths that exist only
|
|
# inside the pod's mount namespace.
|
|
#
|
|
# Security note: mounting the host Docker socket grants the Box runtime (and any
|
|
# code executed in the sandbox) effective root on the node. Only deploy Box on
|
|
# nodes you trust for this workload, ideally a dedicated node pool. For a
|
|
# stronger isolation boundary, switch box.backend to 'e2b' (set E2B_API_KEY) and
|
|
# drop the docker.sock mount + hostPath entirely.
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: langbot-box
|
|
namespace: langbot
|
|
labels:
|
|
app: langbot-box
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: langbot-box
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: langbot-box
|
|
spec:
|
|
# Pin to the same node as langbot so they share the hostPath box root.
|
|
affinity:
|
|
podAffinity:
|
|
requiredDuringSchedulingIgnoredDuringExecution:
|
|
- labelSelector:
|
|
matchLabels:
|
|
app: langbot
|
|
topologyKey: kubernetes.io/hostname
|
|
containers:
|
|
- name: langbot-box
|
|
image: rockchin/langbot:latest
|
|
imagePullPolicy: Always
|
|
# Launched through the same CLI entry point as the plugin runtime.
|
|
# No flag => WebSocket control transport (default), listening on 5410.
|
|
command: ["uv", "run", "--no-sync", "-m", "langbot_plugin.cli.__init__", "box"]
|
|
ports:
|
|
- containerPort: 5410
|
|
name: box-rpc
|
|
protocol: TCP
|
|
env:
|
|
- name: TZ
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: TZ
|
|
- name: LANGBOT_BOX_CONTROL_TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: langbot-box-control
|
|
key: token
|
|
- name: LANGBOT_BLOCKING_EXECUTOR_MAX_WORKERS
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: LANGBOT_BLOCKING_EXECUTOR_MAX_WORKERS
|
|
- name: LANGBOT_BLOCKING_EXECUTOR_MAX_PENDING
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: LANGBOT_BLOCKING_EXECUTOR_MAX_PENDING
|
|
- name: LANGBOT_BLOCKING_EXECUTOR_MAX_INFLIGHT_PER_SCOPE
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: LANGBOT_BLOCKING_EXECUTOR_MAX_INFLIGHT_PER_SCOPE
|
|
# The Box runtime does NOT read box.local.* / BOX__* from its own env;
|
|
# it receives its functional configuration from LangBot via INIT.
|
|
volumeMounts:
|
|
# Box workspace root — identical path on node, box, and sandbox
|
|
# containers (see the IMPORTANT note above).
|
|
- name: box-root
|
|
mountPath: /app/data/box
|
|
# Host Docker socket — the sandbox backend uses it to create containers.
|
|
- name: docker-sock
|
|
mountPath: /var/run/docker.sock
|
|
resources:
|
|
requests:
|
|
memory: "256Mi"
|
|
cpu: "100m"
|
|
limits:
|
|
memory: "1Gi"
|
|
cpu: "1000m"
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 5410
|
|
initialDelaySeconds: 20
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
readinessProbe:
|
|
httpGet:
|
|
# Unlike liveness, readiness validates the configured backend and
|
|
# all strict managed-mode isolation guarantees.
|
|
path: /readyz
|
|
port: 5410
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 5
|
|
timeoutSeconds: 3
|
|
failureThreshold: 3
|
|
volumes:
|
|
- name: box-root
|
|
hostPath:
|
|
path: /app/data/box
|
|
type: DirectoryOrCreate
|
|
- name: docker-sock
|
|
hostPath:
|
|
path: /var/run/docker.sock
|
|
type: Socket
|
|
restartPolicy: Always
|
|
|
|
---
|
|
# Service for LangBot Box runtime
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: langbot-box
|
|
namespace: langbot
|
|
labels:
|
|
app: langbot-box
|
|
spec:
|
|
type: ClusterIP
|
|
selector:
|
|
app: langbot-box
|
|
ports:
|
|
- port: 5410
|
|
targetPort: 5410
|
|
protocol: TCP
|
|
name: box-rpc
|
|
|
|
---
|
|
# Deployment for LangBot
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: langbot
|
|
namespace: langbot
|
|
labels:
|
|
app: langbot
|
|
spec:
|
|
replicas: 1
|
|
# Plugin Runtime has a single active LangBot control owner. Recreate avoids
|
|
# two LangBot pods fighting over that connection during a rolling update.
|
|
strategy:
|
|
type: Recreate
|
|
selector:
|
|
matchLabels:
|
|
app: langbot
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: langbot
|
|
spec:
|
|
containers:
|
|
- name: langbot
|
|
image: rockchin/langbot:latest
|
|
imagePullPolicy: Always
|
|
ports:
|
|
- containerPort: 5300
|
|
name: web
|
|
protocol: TCP
|
|
- containerPort: 2280
|
|
name: webhook-start
|
|
protocol: TCP
|
|
# Note: Kubernetes doesn't support port ranges directly in container ports
|
|
# The webhook ports 2280-2290 are available, but we only expose the start of the range
|
|
# If you need all ports exposed, consider using a Service with multiple port definitions
|
|
env:
|
|
- name: TZ
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: TZ
|
|
- name: PLUGIN__RUNTIME_WS_URL
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: PLUGIN__RUNTIME_WS_URL
|
|
- name: LANGBOT_PLUGIN_RUNTIME_CONTROL_TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: langbot-plugin-runtime-control
|
|
key: token
|
|
- name: SYSTEM__BLOCKING_EXECUTOR__MAX_WORKERS
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: SYSTEM__BLOCKING_EXECUTOR__MAX_WORKERS
|
|
- name: SYSTEM__BLOCKING_EXECUTOR__MAX_PENDING
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: SYSTEM__BLOCKING_EXECUTOR__MAX_PENDING
|
|
- name: SYSTEM__BLOCKING_EXECUTOR__MAX_INFLIGHT_PER_SCOPE
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: SYSTEM__BLOCKING_EXECUTOR__MAX_INFLIGHT_PER_SCOPE
|
|
# Box (sandbox) runtime endpoint. Connects LangBot to the langbot-box
|
|
# Service over WebSocket. Remove this (and the langbot-box Deployment)
|
|
# and set BOX__ENABLED=false if you do not want the sandbox.
|
|
- name: BOX__RUNTIME__ENDPOINT
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: langbot-config
|
|
key: BOX__RUNTIME__ENDPOINT
|
|
# Same Secret as langbot-box. It authenticates the RPC and managed-
|
|
# process relay handshakes and is never put in a URL or RPC payload.
|
|
- name: LANGBOT_BOX_CONTROL_TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: langbot-box-control
|
|
key: token
|
|
# box.local.* config — forwarded to the Box runtime via INIT RPC. The
|
|
# host_root MUST match the box-root hostPath mountPath below AND the box
|
|
# Deployment's box-root mountPath, so that skill package paths resolve
|
|
# identically on both sides and on the node's Docker daemon.
|
|
- name: BOX__LOCAL__HOST_ROOT
|
|
value: "/app/data/box"
|
|
- name: BOX__LOCAL__DEFAULT_WORKSPACE
|
|
value: "default"
|
|
- name: BOX__LOCAL__SKILLS_ROOT
|
|
value: "skills"
|
|
- name: BOX__LOCAL__ALLOWED_MOUNT_ROOTS
|
|
value: "/app/data/box"
|
|
volumeMounts:
|
|
- name: data
|
|
mountPath: /app/data
|
|
- name: plugins
|
|
mountPath: /app/plugins
|
|
# Same node-level box root as the langbot-box Deployment. Mounted over
|
|
# the data PVC's /app/data/box subpath so both LangBot and the Box
|
|
# runtime (and the node's dockerd) agree on one absolute path.
|
|
- name: box-root
|
|
mountPath: /app/data/box
|
|
resources:
|
|
requests:
|
|
memory: "1Gi"
|
|
cpu: "500m"
|
|
limits:
|
|
memory: "4Gi"
|
|
cpu: "2000m"
|
|
# Liveness probe to restart container if it becomes unresponsive
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 5300
|
|
initialDelaySeconds: 60
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
# Readiness probe to know when container is ready to accept traffic
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 5300
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 5
|
|
timeoutSeconds: 3
|
|
failureThreshold: 3
|
|
volumes:
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: langbot-data
|
|
- name: plugins
|
|
persistentVolumeClaim:
|
|
claimName: langbot-plugins
|
|
# Node-level box workspace root, shared with the langbot-box Deployment.
|
|
# hostPath (not PVC) because the node's Docker daemon must see the same
|
|
# absolute path when bind-mounting workspaces into sandbox containers.
|
|
- name: box-root
|
|
hostPath:
|
|
path: /app/data/box
|
|
type: DirectoryOrCreate
|
|
restartPolicy: Always
|
|
|
|
---
|
|
# Service for LangBot (ClusterIP for internal access)
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: langbot
|
|
namespace: langbot
|
|
labels:
|
|
app: langbot
|
|
spec:
|
|
type: ClusterIP
|
|
selector:
|
|
app: langbot
|
|
ports:
|
|
- port: 5300
|
|
targetPort: 5300
|
|
protocol: TCP
|
|
name: web
|
|
- port: 2280
|
|
targetPort: 2280
|
|
protocol: TCP
|
|
name: webhook-2280
|
|
- port: 2281
|
|
targetPort: 2281
|
|
protocol: TCP
|
|
name: webhook-2281
|
|
- port: 2282
|
|
targetPort: 2282
|
|
protocol: TCP
|
|
name: webhook-2282
|
|
- port: 2283
|
|
targetPort: 2283
|
|
protocol: TCP
|
|
name: webhook-2283
|
|
- port: 2284
|
|
targetPort: 2284
|
|
protocol: TCP
|
|
name: webhook-2284
|
|
- port: 2285
|
|
targetPort: 2285
|
|
protocol: TCP
|
|
name: webhook-2285
|
|
- port: 2286
|
|
targetPort: 2286
|
|
protocol: TCP
|
|
name: webhook-2286
|
|
- port: 2287
|
|
targetPort: 2287
|
|
protocol: TCP
|
|
name: webhook-2287
|
|
- port: 2288
|
|
targetPort: 2288
|
|
protocol: TCP
|
|
name: webhook-2288
|
|
- port: 2289
|
|
targetPort: 2289
|
|
protocol: TCP
|
|
name: webhook-2289
|
|
- port: 2290
|
|
targetPort: 2290
|
|
protocol: TCP
|
|
name: webhook-2290
|
|
|
|
---
|
|
# Ingress for external access (Optional - requires Ingress Controller)
|
|
# Uncomment and modify the following section if you want to expose LangBot via Ingress
|
|
# apiVersion: networking.k8s.io/v1
|
|
# kind: Ingress
|
|
# metadata:
|
|
# name: langbot-ingress
|
|
# namespace: langbot
|
|
# annotations:
|
|
# # Uncomment and modify based on your ingress controller
|
|
# # nginx.ingress.kubernetes.io/rewrite-target: /
|
|
# # cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
# spec:
|
|
# ingressClassName: nginx # Change based on your ingress controller
|
|
# rules:
|
|
# - host: langbot.yourdomain.com # Change to your domain
|
|
# http:
|
|
# paths:
|
|
# - path: /
|
|
# pathType: Prefix
|
|
# backend:
|
|
# service:
|
|
# name: langbot
|
|
# port:
|
|
# number: 5300
|
|
# # Uncomment for TLS/HTTPS
|
|
# # tls:
|
|
# # - hosts:
|
|
# # - langbot.yourdomain.com
|
|
# # secretName: langbot-tls
|
|
|
|
---
|
|
# Service for LangBot with LoadBalancer (Alternative to Ingress)
|
|
# Uncomment the following if you want to expose LangBot directly via LoadBalancer
|
|
# This is useful in cloud environments (AWS, GCP, Azure, etc.)
|
|
# apiVersion: v1
|
|
# kind: Service
|
|
# metadata:
|
|
# name: langbot-loadbalancer
|
|
# namespace: langbot
|
|
# labels:
|
|
# app: langbot
|
|
# spec:
|
|
# type: LoadBalancer
|
|
# selector:
|
|
# app: langbot
|
|
# ports:
|
|
# - port: 80
|
|
# targetPort: 5300
|
|
# protocol: TCP
|
|
# name: web
|
|
# - port: 2280
|
|
# targetPort: 2280
|
|
# protocol: TCP
|
|
# name: webhook-start
|
|
# # Add more webhook ports as needed
|
|
|
|
---
|
|
# Service for LangBot with NodePort (Alternative for exposing service)
|
|
# Uncomment if you want to expose LangBot via NodePort
|
|
# This is useful for testing or when LoadBalancer is not available
|
|
# apiVersion: v1
|
|
# kind: Service
|
|
# metadata:
|
|
# name: langbot-nodeport
|
|
# namespace: langbot
|
|
# labels:
|
|
# app: langbot
|
|
# spec:
|
|
# type: NodePort
|
|
# selector:
|
|
# app: langbot
|
|
# ports:
|
|
# - port: 5300
|
|
# targetPort: 5300
|
|
# nodePort: 30300 # Must be in range 30000-32767
|
|
# protocol: TCP
|
|
# name: web
|
|
# - port: 2280
|
|
# targetPort: 2280
|
|
# nodePort: 30280 # Must be in range 30000-32767
|
|
# protocol: TCP
|
|
# name: webhook
|