# 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 ```yaml # 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 ```yaml # 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 ```yaml # 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 ```yaml # 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 ```yaml # 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) ```yaml # 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 ```yaml # 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 ```yaml # 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 ```yaml # 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 ```yaml # 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 ```yaml # 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 ```yaml # 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 ```yaml # 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 ```yaml # 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 ```yaml # 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 ```yaml # 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 ``` ```yaml # 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) ```yaml # 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 ```