How to Deploy Headroom in Docker Using Docker-Compose: Complete Setup Guide

Deploy Headroom by cloning the chopratejas/headroom repository and running docker compose up --build -d, which builds a multi-stage image and orchestrates the Headroom proxy service with Qdrant and Neo4j databases.

Headroom is an open-source knowledge management system that packages its Rust-based core and Python proxy into a production-ready container. To deploy headroom in docker using docker-compose, you leverage a multi-stage build process that isolates compilation dependencies from the runtime environment, resulting in a minimal, secure image. This guide walks through the architecture, configuration files, and deployment commands using the actual source implementation from the repository.

Understanding the Multi-Stage Dockerfile

The Dockerfile at the repository root implements a multi-stage build strategy that separates the heavy build environment from the lightweight runtime. This approach minimizes the final image size and attack surface while ensuring the Rust extensions compile correctly.

The Builder Stage

The builder stage (lines 6-53) uses python-slim as its base image and handles all compilation tasks:

  • Installs system dependencies including build-essential, g++, curl, and patchelf
  • Utilizes the uv package manager to install Python dependencies and build the headroom[proxy,code] wheel in a single step
  • Compiles the Rust-based _core extension from source
  • Executes a smoke test to verify the compiled extension before proceeding to the runtime stage

The Runtime Stage

The final stage defaults to runtime-slim-base (lines 63-99) and creates the production-ready image:

  • Copies only the compiled site-packages from the builder stage, discarding the Rust toolchain and build tools
  • Creates a non-root user for security isolation
  • Exposes port 8787 and configures a health check endpoint at http://127.0.0.1:8787/readyz
  • Sets the entrypoint to execute headroom proxy

Docker-Compose Architecture

The docker-compose.yml file orchestrates three interconnected services that form the complete Headroom stack according to the source definitions (lines 1-50).

Core Services

  • headroom-proxy: Built from the repository Dockerfile, this service exposes the Headroom API on port 8787 and depends on both databases
  • qdrant: Vector database container providing semantic search capabilities through persistent storage
  • neo4j: Graph database container handling knowledge graph storage and relationship queries

Networking and Persistence

Docker Compose automatically creates a dedicated bridge network allowing services to communicate via internal hostnames (qdrant and neo4j). Both database services mount persistent Docker volumes—qdrant_data and neo4j_data—ensuring data survives container restarts.

Step-by-Step Deployment

Follow these commands to deploy the complete stack from source:

  1. Clone the repository and change to the project directory:
git clone https://github.com/chopratejas/headroom.git
cd headroom
  1. Build the images and start all services in detached mode:
docker compose up --build -d
  1. Verify the Headroom service is running by streaming logs:
docker compose logs -f headroom-proxy
  1. Confirm the installation by checking the version inside the container:
docker compose exec headroom-proxy headroom version

Managing the Deployment

Use these commands for common operational tasks:

  • Stop services: docker compose down
  • Stop and remove data volumes: docker compose down -v
  • View service status: docker compose ps
  • Restart single service: docker compose restart headroom-proxy

Customization Options

Custom LLM Endpoints

To point Headroom to a custom OpenAI-compatible API instead of the default, uncomment and configure the OPENAI_TARGET_API_URL environment variable in the headroom-proxy service definition within docker-compose.yml.

Runtime User Configuration

By default, the container runs as a non-root user for security. To override this during the build process, pass the build argument:

docker compose build --build-arg RUNTIME_USER=root headroom-proxy

Distroless Base Image

For minimal security-focused deployments, modify the final stage in the Dockerfile to use runtime-slim (distroless base) instead of runtime-slim-base, then rebuild with docker compose build.

Summary

  • Headroom uses a multi-stage Dockerfile that compiles Rust extensions in an isolated builder stage before copying artifacts to a minimal runtime image exposing port 8787
  • The docker-compose.yml orchestrates three services—headroom-proxy, qdrant, and neo4j—with persistent volumes and internal networking on dedicated Docker networks
  • Deploy the entire stack by running docker compose up --build -d inside the cloned chopratejas/headroom repository
  • The default configuration runs as a non-root user with health checks configured at /readyz and supports customization through build arguments and environment variables

Frequently Asked Questions

What ports need to be open for Headroom to function?

Headroom exposes port 8787 for the proxy API service. The Qdrant and Neo4j services communicate internally within the Docker network via container hostnames and do not require external port exposure for standard operation.

How do I persist data when restarting containers?

The docker-compose.yml defines named volumes qdrant_data and neo4j_data mounted to the respective database containers. Data persists across container restarts unless you explicitly run docker compose down -v, which removes these volumes along with the containers.

Why does the build process use the uv package manager instead of pip?

The builder stage uses uv to rapidly install Python dependencies and build the headroom[proxy,code] wheel in a single step. This approach significantly reduces build time compared to traditional pip install methods while correctly compiling the required Rust extensions and handling binary wheels efficiently.

Can I run Headroom as root inside the container?

While the default configuration runs as a non-root user for security, you can build the image to run as root by setting the RUNTIME_USER=root build argument. Pass this during build: docker compose build --build-arg RUNTIME_USER=root headroom-proxy, though this is not recommended for production deployments.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →