# Deploying Feather DB with Docker: Self-Hosted Context Infrastructure in 10 Minutes > feather-serve ships with a Docker Compose setup, REST API, Atlas admin SPA, and MCP server. Here's the complete production-ready deployment — persistent volume, embedding provider, health checks, and Python client wiring. - **Category**: Tutorial - **Read time**: 7 min read - **Date**: June 16, 2026 - **Author**: Feather DB (Engineering) - **URL**: https://getfeather.store/theory/feather-db-docker-self-hosted --- ## What you're deploying feather-serve is the production interface for Feather DB. It wraps the embedded C++ engine in a FastAPI server that exposes: - A REST API at `/api/v1/` — for Python clients and curl - An MCP server at `/mcp` — for Claude Desktop and MCP-compatible agents - The Atlas admin SPA at `/admin/` — a web UI for browsing memories and running searches The Docker deployment adds persistence (named volume), automatic restart, and environment-based configuration for the embedding provider. ## Step 1: Clone and build ```bash # Clone the feather repository git clone https://github.com/feather-store/feather.git cd feather # Build the Docker image docker compose -f feather-api/docker-compose.yml build # Confirm the image built successfully docker images | grep feather # feather-api latest a1b2c3d4e5f6 2 minutes ago 412MB ``` ## Step 2: Create the .env file Create `feather-api/.env` with your configuration: ```bash # feather-api/.env # API authentication key — set this to a random secret FEATHER_API_KEY=your-secret-api-key-here # Embedding provider — pick one: # Options: gemini | openai | voyage | cohere | ollama FEATHER_EMBED_PROVIDER=gemini # API key for your chosen provider GOOGLE_API_KEY=your-google-api-key # OPENAI_API_KEY=your-openai-api-key # VOYAGE_API_KEY=your-voyage-api-key # COHERE_API_KEY=your-cohere-api-key # Performance tuning FEATHER_LOAD_THREADS=8 # FEATHER_QUANTIZE_RAM=1 # uncomment to enable int8 RAM quantization # Server config FEATHER_PORT=7700 FEATHER_DIM=768 ``` ## Step 3: Review the docker-compose.yml The default compose file in `feather-api/docker-compose.yml`: ```bash version: '3.9' services: feather-api: image: feather-api:latest build: context: . dockerfile: Dockerfile ports: - "${FEATHER_PORT:-7700}:7700" volumes: # Named volume for persistence across container restarts - feather-data:/data environment: - FEATHER_API_KEY=${FEATHER_API_KEY} - FEATHER_EMBED_PROVIDER=${FEATHER_EMBED_PROVIDER:-gemini} - GOOGLE_API_KEY=${GOOGLE_API_KEY:-} - OPENAI_API_KEY=${OPENAI_API_KEY:-} - VOYAGE_API_KEY=${VOYAGE_API_KEY:-} - COHERE_API_KEY=${COHERE_API_KEY:-} - FEATHER_LOAD_THREADS=${FEATHER_LOAD_THREADS:-4} - FEATHER_DIM=${FEATHER_DIM:-768} healthcheck: test: ["CMD", "curl", "-f", "http://localhost:7700/health"] interval: 30s timeout: 10s retries: 3 start_period: 15s restart: unless-stopped volumes: feather-data: driver: local ``` ## Step 4: Start the service ```bash # Start in detached mode docker compose -f feather-api/docker-compose.yml up -d # Watch the logs until the server is ready docker compose -f feather-api/docker-compose.yml logs -f # feather-api | INFO: Feather DB v0.15.1 # feather-api | INFO: Embedding provider: gemini (text-embedding-004) # feather-api | INFO: Index loaded in 0.02s (0 vectors) # feather-api | INFO: Serving at http://0.0.0.0:7700 # feather-api | INFO: Atlas admin at http://0.0.0.0:7700/admin/ # feather-api | INFO: MCP endpoint at http://0.0.0.0:7700/mcp ``` ## Step 5: Verify the health check ```bash # Health check endpoint curl http://localhost:7700/health # {"status": "ok", "version": "0.15.1", "vectors": 0, "dim": 768} # Test with the API key curl -H "Authorization: Bearer your-secret-api-key-here" \ http://localhost:7700/api/v1/stats # {"total_vectors": 0, "namespaces": 0, "file_size_mb": 0.002} ``` ## Step 6: Browse the admin SPA Open `http://localhost:7700/admin/` in your browser. The Atlas admin SPA allows you to: - Browse all stored memories by namespace and entity - Run manual semantic searches and see scores - Inspect memory metadata and recall counts - Add and delete individual memories - View the context graph for any memory The admin SPA is read-write but requires the same API key for any mutations. It's useful for debugging what your agent is remembering and why certain memories surface. ## Step 7: Connect from a Python client ```python import requests FEATHER_URL = "http://localhost:7700" FEATHER_API_KEY = "your-secret-api-key-here" headers = {"Authorization": f"Bearer {FEATHER_API_KEY}"} def add_memory(text: str, namespace: str = "default", entity: str = "general", importance: float = 1.0): """Add a memory via the REST API (text is embedded server-side).""" response = requests.post( f"{FEATHER_URL}/api/v1/add", headers=headers, json={ "text": text, "namespace": namespace, "entity": entity, "importance": importance } ) response.raise_for_status() return response.json() def search_memory(query: str, namespace: str = "default", k: int = 5, half_life: int = 30): """Search memories via the REST API.""" response = requests.post( f"{FEATHER_URL}/api/v1/search", headers=headers, json={ "query": query, "namespace": namespace, "k": k, "half_life": half_life } ) response.raise_for_status() return response.json()["results"] # Usage mem = add_memory( text="The feather-serve Docker deployment uses a named volume for persistence.", namespace="project-docs", entity="deployment", importance=1.5 ) print(f"Saved memory id={mem['id']}") results = search_memory( query="How does Docker persistence work for feather-serve?", namespace="project-docs" ) for r in results: print(f"score={r['score']:.3f}: {r['text'][:80]}") ``` ## Production configuration notes **Named volume:** The `feather-data` named volume persists the `.feather` file across container restarts and image updates. Never use a bind mount to a temporary directory in production — you'll lose all memories on container restart. **Restart policy:** `restart: unless-stopped` ensures the service recovers from crashes and starts on host reboot. Change to `always` if you want it to start even when you manually stopped it. **Embedding provider in Docker:** The embedding provider is set via environment variable. To switch from Gemini to OpenAI, update `FEATHER_EMBED_PROVIDER=openai` and add `OPENAI_API_KEY` in your `.env` file, then restart the container. All existing memories remain valid as long as you use the same embedding dimension. **Reverse proxy:** For production HTTPS, put Nginx or Caddy in front of feather-serve. Add a `proxy_pass http://feather-api:7700` directive and a Let's Encrypt certificate. The MCP endpoint and admin SPA both work behind a reverse proxy with no additional configuration. **Install:** `pip install feather-db` · **GitHub:** [github.com/feather-store/feather](https://github.com/feather-store/feather) --- *This is the machine-readable mirror of the theory post at [getfeather.store/theory/feather-db-docker-self-hosted](https://getfeather.store/theory/feather-db-docker-self-hosted). For the full Feather DB documentation, see [getfeather.store/llms-full.txt](https://getfeather.store/llms-full.txt).*