# RootCauseOS full stack — engine + shim + dashboard + LibreChat + Mongo, behind a # Caddy reverse proxy that auto-provisions Let's Encrypt TLS for the nip.io hostnames. # EVERYTHING points at rca_unseen. The existing systemd rca-api (:8077, rca) is left # untouched — this bundle is a self-contained second stack on the unseen slice. # # cd ~/rca-stack && docker compose -f deploy/docker-compose.yml up -d --build # # Public (TLS): https://dash.23.101.175.68.nip.io (dashboard) # https://chat.23.101.175.68.nip.io (LibreChat) name: rcos-stack x-app-env: &app-env CLICKHOUSE_DATABASE: rca_unseen # the ONE dataset lever — whole stack on unseen services: engine: build: context: .. dockerfile: deploy/Dockerfile image: rcos-app:latest command: uvicorn api.server:app --host 0.0.0.0 --port 8078 env_file: ../.env # run_incident.env() reads a .env FILE for ClickHouse creds (not just process env), # so mount it in addition to env_file. Read-only. volumes: - ../.env:/app/.env:ro environment: <<: *app-env RCOS_ADJUDICATE: "on" # LLM suppression trays ON (the differentiator) RCOS_API: "off" # the engine IS the source; never chase another API expose: ["8078"] healthcheck: test: ["CMD", "curl", "-fsS", "http://localhost:8078/health"] interval: 30s timeout: 10s retries: 5 start_period: 90s restart: unless-stopped shim: image: rcos-app:latest command: python integrations/openai_shim.py env_file: ../.env volumes: - ../.env:/app/.env:ro - ../ui:/app/ui:ro # live code — update via rsync + restart, no rebuild environment: <<: *app-env RCOS_API: http://engine:8078 # shim grounds its chat answers on the unseen engine # published on loopback — host nginx exposes it as https://shim.23.101.175.68.nip.io so the # dashboard's "Ask AI" dock (browser-side fetch) can reach it. CORS is already permissive. ports: - "127.0.0.1:8601:8601" depends_on: engine: condition: service_healthy restart: unless-stopped dashboard: image: rcos-app:latest command: > streamlit run ui/app.py --server.port 8504 --server.address 0.0.0.0 --server.headless true --browser.gatherUsageStats false --server.enableCORS false --server.enableXsrfProtection false env_file: ../.env volumes: - ../.env:/app/.env:ro - ../ui:/app/ui:ro # live code — update via rsync + restart, no rebuild environment: <<: *app-env RCOS_API: http://engine:8078 LIBRECHAT_URL: https://chat.23.101.175.68.nip.io # sidebar "open in LibreChat" link SHIM_URL: https://shim.23.101.175.68.nip.io # "Ask AI" dock backend (browser-side) # published on loopback only — the host's existing nginx terminates TLS and proxies in ports: - "127.0.0.1:8504:8504" depends_on: engine: condition: service_healthy restart: unless-stopped librechat: image: ghcr.io/danny-avila/librechat:v0.8.7 container_name: rcos-librechat env_file: ../.env environment: HOST: 0.0.0.0 MONGO_URI: mongodb://mongodb:27017/LibreChat DOMAIN_CLIENT: https://chat.23.101.175.68.nip.io DOMAIN_SERVER: https://chat.23.101.175.68.nip.io TRUST_PROXY: "1" volumes: - ./librechat.deploy.yaml:/app/librechat.yaml:ro ports: - "127.0.0.1:3080:3080" depends_on: - mongodb - shim restart: unless-stopped mongodb: image: mongo:7 container_name: rcos-mongodb command: mongod --noauth volumes: - mongo-data:/data/db restart: unless-stopped # TLS is terminated by the host's existing nginx (certbot) — see deploy/nginx/ and # deploy/README.md. No Caddy: nginx already owns :80/:443 on this shared VM. volumes: mongo-data: