mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
## Description Pin the top-level Docker Compose proxy service to Headroom's canonical writable workspace under the existing `headroom_workspace` named volume. Closes #1835 The dashboard's durable savings/history data is loaded from `proxy_savings.json` via `HEADROOM_WORKSPACE_DIR`; logs, session stats, TOIN, config, and default workspace state are also derived from that root. The top-level compose file already mounted `/home/nonroot/.headroom`, but it relied on image/user home resolution instead of exporting the canonical workspace env. This makes the official compose contract explicit and matches the Docker-native compose/runtime path behavior. ## Type of Change - [x] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update - [ ] Performance improvement - [ ] Code refactoring (no functional changes) ## Changes Made - Set `HOME=/home/nonroot` for the top-level compose proxy service. - Set `HEADROOM_WORKSPACE_DIR=/home/nonroot/.headroom` and `HEADROOM_CONFIG_DIR=/home/nonroot/.headroom/config` so dashboard savings/history, logs, config, memory state, session stats, and TOIN resolve into the persisted named volume. - Added a regression test that locks the top-level compose persistence wiring. ## Testing - [x] Unit tests pass (`pytest`) — focused local tests and full CI test matrix passed - [x] Linting passes (`ruff check .`) — local Ruff and CI lint passed - [x] Type checking passes (`mypy headroom`) — local mypy and CI lint passed - [x] New tests added for new functionality - [x] Manual testing performed ### Test Output ```text $ rtk pytest tests/test_docker_compose_persistence.py Pytest: 1 passed $ rtk pytest tests/test_docker_compose_persistence.py tests/test_paths.py Pytest: 76 passed $ rtk uvx ruff check tests/test_docker_compose_persistence.py All checks passed! $ rtk docker compose config services: headroom-proxy: environment: HEADROOM_CONFIG_DIR: /home/nonroot/.headroom/config HEADROOM_HOST: 0.0.0.0 HEADROOM_WORKSPACE_DIR: /home/nonroot/.headroom HOME: /home/nonroot volumes: - type: volume source: headroom_workspace target: /home/nonroot/.headroom ``` Attempted broader proxy stats-history coverage, but this local checkout does not have the native extension built: ```text $ rtk pytest tests/test_docker_compose_persistence.py tests/test_paths.py tests/test_proxy_savings_history.py::test_stats_history_persists_across_restarts_and_stats_stays_compatible ModuleNotFoundError: No module named 'headroom._core' ``` Attempted project-managed Ruff, but `uv run` tried to build the editable package first and hit the known local native build issue before Ruff could execute: ```text $ rtk uv run ruff check tests/test_docker_compose_persistence.py error: failed to run custom build command for `esaxx-rs v0.1.10` fatal error: 'cstdint' file not found ``` ## Real Behavior Proof - Environment: local clean clone at current upstream `main`, branch `fix/1835-docker-compose-persistence`. - Exact command / steps: `rtk docker compose config` from the repo root. - Observed result: Compose renders `HOME`, `HEADROOM_WORKSPACE_DIR`, and `HEADROOM_CONFIG_DIR` under `/home/nonroot/.headroom`, and the `headroom_workspace` named volume targets that same path. - Not tested: full Docker image build or live `docker compose up` restart cycle; full pytest/mypy not run locally because this checkout lacks the built `headroom._core` extension. ## Review Readiness - [x] I have performed a self-review - [x] This PR is ready for human review ## Checklist - [x] My code follows the project's style guidelines - [x] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] I have updated the CHANGELOG.md if applicable ## Screenshots (if applicable) N/A ## Additional Notes - All non-skipped GitHub Actions checks are green after the rebase onto `main`; skipped jobs are path-gated. - The dashboard's recent request table is still an in-memory tail and is expected to be empty after a proxy restart. This PR targets durable dashboard savings/history and other workspace-backed files. - `HEADROOM_LOG_FILE=/home/nonroot/.headroom/requests.jsonl` remains an optional operator setting; persisted request JSONL is not replayed into the dashboard after restart. - The docs/CHANGELOG checklist items are N/A for this narrow compose configuration fix.
57 lines
1.7 KiB
YAML
57 lines
1.7 KiB
YAML
services:
|
|
headroom-proxy:
|
|
build: .
|
|
command: ["--host", "0.0.0.0"]
|
|
environment:
|
|
- HEADROOM_HOST=0.0.0.0
|
|
- HOME=/home/nonroot
|
|
# Keep all Headroom read/write state on the named volume below.
|
|
- HEADROOM_WORKSPACE_DIR=/home/nonroot/.headroom
|
|
- HEADROOM_CONFIG_DIR=/home/nonroot/.headroom/config
|
|
# if you want to use a custom OpenAI-compatible API endpoint,
|
|
# uncomment and set the following line with the desired URL
|
|
# - OPENAI_TARGET_API_URL=https://api.x.ai
|
|
ports:
|
|
- "8787:8787"
|
|
volumes:
|
|
- headroom_workspace:/home/nonroot/.headroom
|
|
healthcheck:
|
|
test: ["CMD", "curl", "--fail", "--silent", "http://127.0.0.1:8787/readyz"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 20s
|
|
depends_on:
|
|
- qdrant
|
|
- neo4j
|
|
|
|
# Vector database for semantic search
|
|
qdrant:
|
|
image: qdrant/qdrant:v1.17.1
|
|
ports:
|
|
- "6333:6333" # REST API
|
|
- "6334:6334" # gRPC
|
|
volumes:
|
|
- qdrant_data:/qdrant/storage
|
|
environment:
|
|
- QDRANT__SERVICE__GRPC_PORT=6334
|
|
|
|
# Graph database for relationships and multi-hop reasoning
|
|
neo4j:
|
|
image: neo4j:5.26
|
|
ports:
|
|
- "7474:7474" # HTTP (Browser)
|
|
- "7687:7687" # Bolt
|
|
volumes:
|
|
- neo4j_data:/data
|
|
environment:
|
|
- NEO4J_AUTH=${NEO4J_AUTH:-neo4j/devpassword}
|
|
- NEO4J_PLUGINS=["apoc"]
|
|
- NEO4J_apoc_export_file_enabled=true
|
|
- NEO4J_apoc_import_file_enabled=true
|
|
- NEO4J_apoc_import_file_use__neo4j__config=true
|
|
|
|
volumes:
|
|
headroom_workspace: # persists dashboard savings/history, logs, config, memory state, session stats, and TOIN
|
|
qdrant_data:
|
|
neo4j_data:
|