33 KiB
33 KiB
VAULTMESH-DEPLOYMENT-MANIFESTS.md
Production Infrastructure for the Civilization Ledger
A system that cannot be deployed is a system that cannot exist.
This document provides complete Kubernetes, Docker, and infrastructure-as-code configurations for deploying VaultMesh in production environments.
1. Deployment Architecture
┌─────────────────────────────────────────────────────────────────────────┐
│ KUBERNETES CLUSTER │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ INGRESS LAYER │ │
│ │ • Traefik / NGINX Ingress │ │
│ │ • TLS termination (cert-manager) │ │
│ │ • Rate limiting │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────┼─────────────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ PORTAL │ │ GUARDIAN │ │ ORACLE │ │
│ │ (Rust) │ │ (Rust) │ │ (Python) │ │
│ │ │ │ │ │ │ │
│ │ • HTTP API │ │ • Anchor │ │ • MCP Server │ │
│ │ • WebSocket │ │ • ProofChain │ │ • LLM Client │ │
│ │ • Auth │ │ • Sentinel │ │ • Corpus │ │
│ └───────┬───────┘ └───────┬───────┘ └───────┬───────┘ │
│ │ │ │ │
│ └───────────────────────┼───────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ DATA LAYER │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ PostgreSQL │ │ Redis │ │ MinIO │ │ │
│ │ │ (receipts) │ │ (cache) │ │ (artifacts) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ PERSISTENT VOLUMES │ │ │
│ │ │ • receipts/ (JSONL files) │ │ │
│ │ │ • cases/ (artifacts) │ │ │
│ │ │ • corpus/ (Oracle documents) │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ OBSERVABILITY LAYER │ │
│ │ • Prometheus (metrics) │ │
│ │ • Loki (logs) │ │
│ │ • Tempo (traces) │ │
│ │ • Grafana (dashboards) │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
2. Namespace and RBAC
2.1 Namespace
# kubernetes/base/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: vaultmesh
labels:
app.kubernetes.io/name: vaultmesh
app.kubernetes.io/part-of: civilization-ledger
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
2.2 Service Accounts
# kubernetes/base/rbac.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: vaultmesh-portal
namespace: vaultmesh
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: vaultmesh-guardian
namespace: vaultmesh
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: vaultmesh-oracle
namespace: vaultmesh
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: vaultmesh-guardian-role
namespace: vaultmesh
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
resourceNames: ["guardian-anchor-keys", "guardian-config"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch", "update"]
resourceNames: ["vaultmesh-roots", "guardian-state"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: vaultmesh-guardian-binding
namespace: vaultmesh
subjects:
- kind: ServiceAccount
name: vaultmesh-guardian
namespace: vaultmesh
roleRef:
kind: Role
name: vaultmesh-guardian-role
apiGroup: rbac.authorization.k8s.io
3. Core Services
3.1 Portal Deployment
# kubernetes/base/portal/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: vaultmesh-portal
namespace: vaultmesh
labels:
app.kubernetes.io/name: portal
app.kubernetes.io/component: api
app.kubernetes.io/part-of: vaultmesh
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: portal
template:
metadata:
labels:
app.kubernetes.io/name: portal
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
prometheus.io/path: "/metrics"
spec:
serviceAccountName: vaultmesh-portal
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: portal
image: ghcr.io/vaultmesh/portal:v0.1.0
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
ports:
- name: http
containerPort: 8080
protocol: TCP
- name: metrics
containerPort: 9090
protocol: TCP
env:
- name: RUST_LOG
value: "info,vaultmesh=debug"
- name: VAULTMESH_CONFIG
value: "/config/portal.toml"
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: vaultmesh-db-credentials
key: portal-url
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: vaultmesh-redis-credentials
key: url
volumeMounts:
- name: config
mountPath: /config
readOnly: true
- name: receipts
mountPath: /data/receipts
- name: tmp
mountPath: /tmp
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 1000m
memory: 1Gi
livenessProbe:
httpGet:
path: /health/live
port: http
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /health/ready
port: http
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: config
configMap:
name: vaultmesh-portal-config
- name: receipts
persistentVolumeClaim:
claimName: vaultmesh-receipts
- name: tmp
emptyDir: {}
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/name: portal
topologyKey: kubernetes.io/hostname
---
apiVersion: v1
kind: Service
metadata:
name: vaultmesh-portal
namespace: vaultmesh
spec:
selector:
app.kubernetes.io/name: portal
ports:
- name: http
port: 80
targetPort: http
- name: metrics
port: 9090
targetPort: metrics
type: ClusterIP
3.2 Guardian Deployment
# kubernetes/base/guardian/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: vaultmesh-guardian
namespace: vaultmesh
labels:
app.kubernetes.io/name: guardian
app.kubernetes.io/component: anchor
app.kubernetes.io/part-of: vaultmesh
spec:
replicas: 1 # Single instance for anchor coordination
strategy:
type: Recreate # Ensure only one instance runs at a time
selector:
matchLabels:
app.kubernetes.io/name: guardian
template:
metadata:
labels:
app.kubernetes.io/name: guardian
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
spec:
serviceAccountName: vaultmesh-guardian
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: guardian
image: ghcr.io/vaultmesh/guardian:v0.1.0
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
ports:
- name: http
containerPort: 8081
protocol: TCP
- name: metrics
containerPort: 9090
protocol: TCP
env:
- name: RUST_LOG
value: "info,guardian=debug"
- name: GUARDIAN_CONFIG
value: "/config/guardian.toml"
- name: GUARDIAN_ANCHOR_KEY
valueFrom:
secretKeyRef:
name: guardian-anchor-keys
key: private-key
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: vaultmesh-db-credentials
key: guardian-url
volumeMounts:
- name: config
mountPath: /config
readOnly: true
- name: receipts
mountPath: /data/receipts
- name: guardian-state
mountPath: /data/guardian
- name: tmp
mountPath: /tmp
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
livenessProbe:
httpGet:
path: /health/live
port: http
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /health/ready
port: http
initialDelaySeconds: 10
periodSeconds: 5
volumes:
- name: config
configMap:
name: vaultmesh-guardian-config
- name: receipts
persistentVolumeClaim:
claimName: vaultmesh-receipts
- name: guardian-state
persistentVolumeClaim:
claimName: vaultmesh-guardian-state
- name: tmp
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: vaultmesh-guardian
namespace: vaultmesh
spec:
selector:
app.kubernetes.io/name: guardian
ports:
- name: http
port: 80
targetPort: http
- name: metrics
port: 9090
targetPort: metrics
type: ClusterIP
3.3 Oracle Deployment
# kubernetes/base/oracle/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: vaultmesh-oracle
namespace: vaultmesh
labels:
app.kubernetes.io/name: oracle
app.kubernetes.io/component: compliance
app.kubernetes.io/part-of: vaultmesh
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: oracle
template:
metadata:
labels:
app.kubernetes.io/name: oracle
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
spec:
serviceAccountName: vaultmesh-oracle
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: oracle
image: ghcr.io/vaultmesh/oracle:v0.1.0
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
ports:
- name: http
containerPort: 8082
protocol: TCP
- name: mcp
containerPort: 8083
protocol: TCP
- name: metrics
containerPort: 9090
protocol: TCP
env:
- name: ORACLE_CONFIG
value: "/config/oracle.toml"
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: oracle-llm-credentials
key: openai-key
- name: ANTHROPIC_API_KEY
valueFrom:
secretKeyRef:
name: oracle-llm-credentials
key: anthropic-key
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: vaultmesh-db-credentials
key: oracle-url
- name: VAULTMESH_RECEIPT_ENDPOINT
value: "http://vaultmesh-portal/api/receipts"
volumeMounts:
- name: config
mountPath: /config
readOnly: true
- name: corpus
mountPath: /data/corpus
readOnly: true
- name: cache
mountPath: /data/cache
- name: tmp
mountPath: /tmp
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 2000m
memory: 4Gi
livenessProbe:
httpGet:
path: /health/live
port: http
initialDelaySeconds: 20
periodSeconds: 10
readinessProbe:
httpGet:
path: /health/ready
port: http
initialDelaySeconds: 15
periodSeconds: 5
volumes:
- name: config
configMap:
name: vaultmesh-oracle-config
- name: corpus
persistentVolumeClaim:
claimName: vaultmesh-corpus
- name: cache
emptyDir:
sizeLimit: 1Gi
- name: tmp
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: vaultmesh-oracle
namespace: vaultmesh
spec:
selector:
app.kubernetes.io/name: oracle
ports:
- name: http
port: 80
targetPort: http
- name: mcp
port: 8083
targetPort: mcp
- name: metrics
port: 9090
targetPort: metrics
type: ClusterIP
4. Data Layer
4.1 PostgreSQL (via CloudNativePG)
# kubernetes/base/database/postgresql.yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: vaultmesh-db
namespace: vaultmesh
spec:
instances: 3
postgresql:
parameters:
max_connections: "200"
shared_buffers: "256MB"
effective_cache_size: "768MB"
maintenance_work_mem: "128MB"
checkpoint_completion_target: "0.9"
wal_buffers: "16MB"
default_statistics_target: "100"
random_page_cost: "1.1"
effective_io_concurrency: "200"
work_mem: "6553kB"
min_wal_size: "1GB"
max_wal_size: "4GB"
storage:
size: 50Gi
storageClass: fast-ssd
backup:
barmanObjectStore:
destinationPath: "s3://vaultmesh-backups/postgresql"
s3Credentials:
accessKeyId:
name: vaultmesh-backup-credentials
key: access-key
secretAccessKey:
name: vaultmesh-backup-credentials
key: secret-key
wal:
compression: gzip
maxParallel: 8
retentionPolicy: "30d"
monitoring:
enablePodMonitor: true
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 4Gi
---
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: vaultmesh-db-daily-backup
namespace: vaultmesh
spec:
schedule: "0 2 * * *"
backupOwnerReference: self
cluster:
name: vaultmesh-db
4.2 Redis
# kubernetes/base/cache/redis.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: vaultmesh-redis
namespace: vaultmesh
spec:
serviceName: vaultmesh-redis
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: redis
template:
metadata:
labels:
app.kubernetes.io/name: redis
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
command:
- redis-server
- /config/redis.conf
volumeMounts:
- name: config
mountPath: /config
- name: data
mountPath: /data
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 1Gi
volumes:
- name: config
configMap:
name: vaultmesh-redis-config
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: fast-ssd
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
name: vaultmesh-redis
namespace: vaultmesh
spec:
selector:
app.kubernetes.io/name: redis
ports:
- port: 6379
targetPort: 6379
type: ClusterIP
4.3 Persistent Volumes
# kubernetes/base/storage/persistent-volumes.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vaultmesh-receipts
namespace: vaultmesh
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-csi
resources:
requests:
storage: 100Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vaultmesh-guardian-state
namespace: vaultmesh
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-ssd
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vaultmesh-corpus
namespace: vaultmesh
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-csi
resources:
requests:
storage: 50Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vaultmesh-cases
namespace: vaultmesh
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-csi
resources:
requests:
storage: 200Gi
5. Configuration
5.1 Portal Config
# kubernetes/base/portal/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: vaultmesh-portal-config
namespace: vaultmesh
data:
portal.toml: |
[server]
bind = "0.0.0.0:8080"
metrics_bind = "0.0.0.0:9090"
[database]
max_connections = 20
min_connections = 5
[receipts]
base_path = "/data/receipts"
[scrolls]
enabled = [
"Drills",
"Compliance",
"Guardian",
"Treasury",
"Mesh",
"OffSec",
"Identity",
"Observability",
"Automation",
"PsiField",
"Federation",
"Governance",
]
[auth]
jwt_issuer = "vaultmesh-portal"
session_ttl_hours = 24
[guardian]
endpoint = "http://vaultmesh-guardian"
[oracle]
endpoint = "http://vaultmesh-oracle"
5.2 Guardian Config
# kubernetes/base/guardian/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: vaultmesh-guardian-config
namespace: vaultmesh
data:
guardian.toml: |
[server]
bind = "0.0.0.0:8081"
metrics_bind = "0.0.0.0:9090"
[proofchain]
receipts_path = "/data/receipts"
roots_path = "/data/receipts"
[anchor]
# Primary anchor backend
primary = "ethereum"
# Anchor schedule
interval_seconds = 3600 # Every hour
min_receipts_threshold = 10
# Ethereum configuration
[anchor.ethereum]
rpc_url = "https://mainnet.infura.io/v3/${INFURA_PROJECT_ID}"
contract_address = "0x..."
chain_id = 1
gas_limit = 100000
# OpenTimestamps backup
[anchor.ots]
enabled = true
calendar_urls = [
"https://a.pool.opentimestamps.org",
"https://b.pool.opentimestamps.org",
]
# Bitcoin anchor (optional, for high-value anchors)
[anchor.bitcoin]
enabled = false
rpc_url = "http://bitcoin-node:8332"
[sentinel]
enabled = true
alert_webhook = "http://alertmanager:9093/api/v2/alerts"
[state]
path = "/data/guardian/state.json"
5.3 Oracle Config
# kubernetes/base/oracle/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: vaultmesh-oracle-config
namespace: vaultmesh
data:
oracle.toml: |
[server]
http_bind = "0.0.0.0:8082"
mcp_bind = "0.0.0.0:8083"
metrics_bind = "0.0.0.0:9090"
[corpus]
path = "/data/corpus"
index_path = "/data/cache/index"
supported_formats = ["docx", "pdf", "md", "txt"]
[llm]
# Primary model
primary_provider = "anthropic"
primary_model = "claude-sonnet-4-20250514"
# Fallback model
fallback_provider = "openai"
fallback_model = "gpt-4o"
# Settings
temperature = 0.1
max_tokens = 4096
timeout_seconds = 60
[prompts]
version = "vm_oracle_answer_v1"
[receipts]
endpoint = "http://vaultmesh-portal/api/receipts/oracle"
[cache]
enabled = true
path = "/data/cache/answers"
ttl_hours = 24
6. Ingress and TLS
6.1 Ingress
# kubernetes/base/ingress/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: vaultmesh-ingress
namespace: vaultmesh
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
spec:
ingressClassName: nginx
tls:
- hosts:
- portal.vaultmesh.io
- guardian.vaultmesh.io
- oracle.vaultmesh.io
- federation.vaultmesh.io
secretName: vaultmesh-tls
rules:
- host: portal.vaultmesh.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vaultmesh-portal
port:
name: http
- host: guardian.vaultmesh.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vaultmesh-guardian
port:
name: http
- host: oracle.vaultmesh.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vaultmesh-oracle
port:
name: http
- host: federation.vaultmesh.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vaultmesh-portal
port:
name: http
6.2 Certificate
# kubernetes/base/ingress/certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: vaultmesh-tls
namespace: vaultmesh
spec:
secretName: vaultmesh-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- portal.vaultmesh.io
- guardian.vaultmesh.io
- oracle.vaultmesh.io
- federation.vaultmesh.io
7. Secrets Management
7.1 Sealed Secrets
# kubernetes/base/secrets/sealed-secrets.yaml
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: vaultmesh-db-credentials
namespace: vaultmesh
spec:
encryptedData:
portal-url: AgBy3i4OJSWK+PiTySYZZA9rO53sFO...
guardian-url: AgBy3i4OJSWK+PiTySYZZA9rO53sFO...
oracle-url: AgBy3i4OJSWK+PiTySYZZA9rO53sFO...
template:
metadata:
name: vaultmesh-db-credentials
namespace: vaultmesh
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: guardian-anchor-keys
namespace: vaultmesh
spec:
encryptedData:
private-key: AgBy3i4OJSWK+PiTySYZZA9rO53sFO...
template:
metadata:
name: guardian-anchor-keys
namespace: vaultmesh
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: oracle-llm-credentials
namespace: vaultmesh
spec:
encryptedData:
openai-key: AgBy3i4OJSWK+PiTySYZZA9rO53sFO...
anthropic-key: AgBy3i4OJSWK+PiTySYZZA9rO53sFO...
template:
metadata:
name: oracle-llm-credentials
namespace: vaultmesh
8. Kustomization
8.1 Base Kustomization
# kubernetes/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: vaultmesh
resources:
- namespace.yaml
- rbac.yaml
- portal/deployment.yaml
- portal/configmap.yaml
- guardian/deployment.yaml
- guardian/configmap.yaml
- oracle/deployment.yaml
- oracle/configmap.yaml
- database/postgresql.yaml
- cache/redis.yaml
- storage/persistent-volumes.yaml
- ingress/ingress.yaml
- ingress/certificate.yaml
- secrets/sealed-secrets.yaml
commonLabels:
app.kubernetes.io/part-of: vaultmesh
app.kubernetes.io/managed-by: kustomize
8.2 Production Overlay
# kubernetes/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: vaultmesh
resources:
- ../../base
patches:
- path: portal-resources.yaml
- path: guardian-resources.yaml
- path: oracle-resources.yaml
configMapGenerator:
- name: vaultmesh-portal-config
behavior: merge
files:
- portal.toml=configs/portal-prod.toml
- name: vaultmesh-guardian-config
behavior: merge
files:
- guardian.toml=configs/guardian-prod.toml
replicas:
- name: vaultmesh-portal
count: 3
- name: vaultmesh-oracle
count: 3
# kubernetes/overlays/production/portal-resources.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: vaultmesh-portal
spec:
template:
spec:
containers:
- name: portal
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 4Gi
9. Docker Compose (Development)
# docker-compose.yaml
version: "3.9"
services:
portal:
build:
context: .
dockerfile: docker/portal/Dockerfile
ports:
- "8080:8080"
- "9090:9090"
environment:
- RUST_LOG=info,vaultmesh=debug
- VAULTMESH_CONFIG=/config/portal.toml
- DATABASE_URL=postgresql://vaultmesh:vaultmesh@postgres:5432/vaultmesh
- REDIS_URL=redis://redis:6379
volumes:
- ./config/portal.toml:/config/portal.toml:ro
- receipts:/data/receipts
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
interval: 10s
timeout: 5s
retries: 5
guardian:
build:
context: .
dockerfile: docker/guardian/Dockerfile
ports:
- "8081:8081"
environment:
- RUST_LOG=info,guardian=debug
- GUARDIAN_CONFIG=/config/guardian.toml
- DATABASE_URL=postgresql://vaultmesh:vaultmesh@postgres:5432/vaultmesh
volumes:
- ./config/guardian.toml:/config/guardian.toml:ro
- receipts:/data/receipts
- guardian-state:/data/guardian
depends_on:
portal:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8081/health/live"]
interval: 10s
timeout: 5s
retries: 5
oracle:
build:
context: .
dockerfile: docker/oracle/Dockerfile
ports:
- "8082:8082"
- "8083:8083"
environment:
- ORACLE_CONFIG=/config/oracle.toml
- OPENAI_API_KEY=${OPENAI_API_KEY}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- VAULTMESH_RECEIPT_ENDPOINT=http://portal:8080/api/receipts
volumes:
- ./config/oracle.toml:/config/oracle.toml:ro
- ./corpus:/data/corpus:ro
depends_on:
portal:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8082/health/live"]
interval: 10s
timeout: 5s
retries: 5
postgres:
image: postgres:16-alpine
environment:
- POSTGRES_USER=vaultmesh
- POSTGRES_PASSWORD=vaultmesh
- POSTGRES_DB=vaultmesh
volumes:
- postgres-data:/var/lib/postgresql/data
- ./docker/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U vaultmesh"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
command: redis-server --appendonly yes
prometheus:
image: prom/prometheus:v2.47.0
ports:
- "9091:9090"
volumes:
- ./config/prometheus.yaml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.enable-lifecycle'
grafana:
image: grafana/grafana:10.1.0
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- ./config/grafana/provisioning:/etc/grafana/provisioning:ro
- grafana-data:/var/lib/grafana
depends_on:
- prometheus
volumes:
receipts:
guardian-state:
postgres-data:
redis-data:
prometheus-data:
grafana-data:
networks:
default:
name: vaultmesh