> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cyborg.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Docker Service Quickstart

**CyborgDB** can be deployed as a standalone microservice using Docker. This allows you to run a fully self-contained encrypted vector search service on your own infrastructure with minimal setup. The service exposes a REST API for integration with any stack.

<Tip>Looking to use the Python service? Check out our [Python Quickstart Guide](./quickstart-python).</Tip>

## Overview

The Docker service is ideal for teams looking to self-host CyborgDB in cloud, on-prem, or containerized environments.

<Steps>
  <Step title="Get an API Key (Optional)">
    The service runs without an API key — leave `CYBORGDB_API_KEY` unset and the core engine starts in free-tier mode, capped at 1,000,000 items per index. Set it to lift that cap. Get a key from the [CyborgDB Admin Dashboard](https://cyborgdb.co/new), or generate a temporary demo key with any of the SDKs:

    <CodeGroup>
      ```python Python theme={null}
      import cyborgdb
      print(cyborgdb.get_demo_api_key())
      ```

      ```javascript JavaScript theme={null}
      import { getDemoApiKey } from 'cyborgdb';
      console.log(await getDemoApiKey());
      ```

      ```go Go theme={null}
      demoKey, _ := cyborgdb.GetDemoAPIKey("my demo app")
      fmt.Println(demoKey)
      ```
    </CodeGroup>

    Pass the key as `CYBORGDB_API_KEY` when starting the service. This is the core license key, not a service-authentication credential — it does not gate access to the REST API.

    <Note>
      Service authentication is separate and controlled by `CYBORGDB_SERVICE_ROOT_KEY`. Leave it unset (the default) and the service accepts all requests. Set it to require callers to send the root key — or a `cdbk_` user token minted under it — in the `X-API-Key` header. See [Managing Keys](../advanced/managing-keys).
    </Note>
  </Step>

  <Step title="Choose Your Storage Backend (Optional)">
    The container ships with two storage backends. Skip this
    step and you get **disk** by default —
    persisted in `/app/cyborgdb_data` inside the container, which
    you'll typically bind to a host volume.

    * **Disk** (default) — persistent local disk, no
      external dependencies.
    * **S3** — AWS S3 or any S3-compatible store (MinIO,
      Cloudflare R2, …). Best for cloud-native deployments.

    For full details, see the [Backing Stores guide](../../../intro/backing-stores).
  </Step>

  <Step title="Pull the Docker Image">
    The CyborgDB service is available as a Docker image. You can pull it from Docker Hub:

    ```bash theme={null}
    docker pull cyborginc/cyborgdb-service:latest
    ```

    This image contains everything you need to run the CyborgDB service, including all dependencies and configurations.
  </Step>

  <Step title="Run with Docker (Quick Start)">
    Evaluating? Use `docker run` below. Deploying? Use Docker Compose in the next step.

    <Tabs>
      <Tab title="Disk (default)">
        <CodeGroup>
          ```bash Linux theme={null}
          # Minimal — no API key needed; disk is the default; bind the data dir to a host volume
          docker run -it --rm --network host \
            -v cyborgdb_data:/app/cyborgdb_data \
            cyborginc/cyborgdb-service:latest
          ```

          ```bash macOS theme={null}
          docker run -it -p 8000:8000 \
            -v cyborgdb_data:/app/cyborgdb_data \
            cyborginc/cyborgdb-service:latest
          ```
        </CodeGroup>

        <Note>Inside the container the disk path defaults to `/app/cyborgdb_data` — the `-v` mount above is what makes the data survive container recreation. Add `-e CYBORGDB_API_KEY=…` to lift the free-tier 1M-items-per-index cap.</Note>
      </Tab>

      <Tab title="S3 (AWS)">
        <CodeGroup>
          ```bash Linux theme={null}
          docker run -it --network host \
            -e CYBORGDB_DB_TYPE=s3 \
            -e CYBORGDB_S3_BUCKET=my-bucket \
            -e CYBORGDB_S3_REGION=us-east-1 \
            -e AWS_ACCESS_KEY_ID=AKID... \
            -e AWS_SECRET_ACCESS_KEY=... \
            cyborginc/cyborgdb-service:latest
          ```

          ```bash macOS theme={null}
          docker run -it -p 8000:8000 \
            -e CYBORGDB_DB_TYPE=s3 \
            -e CYBORGDB_S3_BUCKET=my-bucket \
            -e CYBORGDB_S3_REGION=us-east-1 \
            -e AWS_ACCESS_KEY_ID=AKID... \
            -e AWS_SECRET_ACCESS_KEY=... \
            cyborginc/cyborgdb-service:latest
          ```
        </CodeGroup>

        <Note>On EC2/ECS/EKS the instance/task role is picked up automatically — drop the `AWS_*` vars.</Note>
      </Tab>

      <Tab title="S3 (MinIO / R2)">
        <CodeGroup>
          ```bash Linux theme={null}
          docker run -it --network host \
            -e CYBORGDB_DB_TYPE=s3 \
            -e CYBORGDB_S3_BUCKET=my-bucket \
            -e CYBORGDB_S3_ENDPOINT=http://minio:9000 \
            -e CYBORGDB_S3_ACCESS_KEY=minioadmin \
            -e CYBORGDB_S3_SECRET_KEY=minioadmin \
            cyborginc/cyborgdb-service:latest
          ```

          ```bash macOS theme={null}
          docker run -it -p 8000:8000 \
            -e CYBORGDB_DB_TYPE=s3 \
            -e CYBORGDB_S3_BUCKET=my-bucket \
            -e CYBORGDB_S3_ENDPOINT=http://host.docker.internal:9000 \
            -e CYBORGDB_S3_ACCESS_KEY=minioadmin \
            -e CYBORGDB_S3_SECRET_KEY=minioadmin \
            cyborginc/cyborgdb-service:latest
          ```
        </CodeGroup>

        <Note>With a custom `CYBORGDB_S3_ENDPOINT` the AWS default credential chain is bypassed entirely — `CYBORGDB_S3_ACCESS_KEY` / `CYBORGDB_S3_SECRET_KEY` are required.</Note>
      </Tab>
    </Tabs>

    <Note>
      **Platform Differences:**

      * **Linux** uses `--network host` because Docker runs natively and can directly access the host network
      * **macOS** uses `-p 8000:8000` and `host.docker.internal` because Docker runs in a VM and needs port mapping
    </Note>
  </Step>

  <Step title="Run with Docker Compose (Recommended)">
    For a reproducible setup, use Docker Compose:

    <Tabs>
      <Tab title="Disk (default)">
        Create a `docker-compose.yml` file:

        ```yaml theme={null}
        services:
          cyborgdb:
            image: cyborginc/cyborgdb-service:latest
            ports:
              - "8000:8000"
            # No API key needed; add CYBORGDB_API_KEY to lift the free-tier cap:
            # environment:
            #   - CYBORGDB_API_KEY=${CYBORGDB_API_KEY}
            volumes:
              - cyborgdb_data:/app/cyborgdb_data
              - ./logs:/app/logs

        volumes:
          cyborgdb_data:
        ```

        Then run:

        ```bash theme={null}
        docker compose up -d
        ```
      </Tab>

      <Tab title="S3 (AWS)">
        Create a `docker-compose.yml` file:

        ```yaml theme={null}
        services:
          cyborgdb:
            image: cyborginc/cyborgdb-service:latest
            ports:
              - "8000:8000"
            environment:
              - CYBORGDB_API_KEY=${CYBORGDB_API_KEY}
              - CYBORGDB_DB_TYPE=s3
              - CYBORGDB_S3_BUCKET=${CYBORGDB_S3_BUCKET}
              - CYBORGDB_S3_REGION=${CYBORGDB_S3_REGION:-us-east-1}
              - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
              - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
        ```

        Then run:

        ```bash theme={null}
        docker compose up -d
        ```
      </Tab>

      <Tab title="S3 (MinIO)">
        Bring up MinIO + cyborgdb-service together:

        ```yaml theme={null}
        services:
          minio:
            image: minio/minio:latest
            command: server /data --console-address ":9001"
            environment:
              - MINIO_ROOT_USER=minioadmin
              - MINIO_ROOT_PASSWORD=minioadmin
            ports:
              - "9000:9000"
              - "9001:9001"
            volumes:
              - minio_data:/data

          cyborgdb:
            image: cyborginc/cyborgdb-service:latest
            ports:
              - "8000:8000"
            environment:
              - CYBORGDB_API_KEY=${CYBORGDB_API_KEY}
              - CYBORGDB_DB_TYPE=s3
              - CYBORGDB_S3_BUCKET=cyborgdb
              - CYBORGDB_S3_ENDPOINT=http://minio:9000
              - CYBORGDB_S3_ACCESS_KEY=minioadmin
              - CYBORGDB_S3_SECRET_KEY=minioadmin
            depends_on:
              - minio

        volumes:
          minio_data:
        ```

        Then run:

        ```bash theme={null}
        docker compose up -d
        ```

        <Note>Create the `cyborgdb` bucket once via the MinIO console (`http://localhost:9001`) before first use.</Note>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Verify Installation">
    Once the service is running, verify it's working correctly:

    **Health Check:**

    ```bash theme={null}
    curl http://localhost:8000/v1/health
    ```

    **API Documentation:**
    Navigate to [http://localhost:8000/v1/docs](http://localhost:8000/v1/docs) to explore the interactive API documentation.

    You should see a response indicating the service is healthy and ready to accept requests.
  </Step>

  <Step title="Run Your First Query">
    With the service running, install the Python client and complete a full connect → index → upsert → query loop:

    ```bash theme={null}
    pip install cyborgdb
    ```

    ```python Python icon="python" theme={null}
    import cyborgdb
    import secrets

    # Connect to the running service.
    client = cyborgdb.Client(base_url="http://localhost:8000")

    # Generate an encryption key for the index.
    # WARNING: store this key securely — data encrypted with a lost key is unrecoverable.
    index_key = secrets.token_bytes(32)

    # Create an encrypted index.
    index = client.create_index(index_name="my_index", index_key=index_key)

    # Upsert some items.
    items = [
        {"id": "item_1", "vector": [0.1, 0.2, 0.3, 0.4], "contents": "Hello!"},
        {"id": "item_2", "vector": [0.5, 0.6, 0.7, 0.8], "contents": "Bonjour!"},
        {"id": "item_3", "vector": [0.9, 0.10, 0.11, 0.12], "contents": "Hola!"},
    ]
    index.upsert(items)

    # Query — include distance + metadata, then chain get() for contents.
    results = index.query(
        query_vectors=[0.1, 0.2, 0.3, 0.4],
        top_k=2,
        include=["distance", "metadata"],
    )
    top_items = index.get([r["id"] for r in results])
    by_id = {item["id"]: item for item in top_items}
    for r in results:
        contents = by_id[r["id"]]["contents"]
        print(f"ID: {r['id']}  Distance: {r['distance']:.4f}  Contents: {contents}")
    ```

    <Warning>
      **Store `index_key` before you upsert any data.** CyborgDB has no key-recovery path — data encrypted with a lost key is unrecoverable. For anything past evaluation, keep the key in AWS Secrets Manager, Vault, or your KMS. See [Managing Keys](../advanced/managing-keys).
    </Warning>

    <Note>
      `index_key` is a 32-byte per-index encryption key you generate and hold. It's separate from `CYBORGDB_API_KEY` (the core license key) and `CYBORGDB_SERVICE_ROOT_KEY` (service authentication).
    </Note>
  </Step>

  <Step title="Advanced Configuration">
    For production deployments, consider these additional configurations:

    <Tabs>
      <Tab title="Environment Variables">
        | Variable | Description | Required | Example |
        | - | - | - | - |
        | `CYBORGDB_API_KEY` | Core license key. Free tier (1M items/index) when unset | ❌ | `cyborg_abc123...` |
        | `CYBORGDB_SERVICE_ROOT_KEY` | Service auth root (an operator-chosen secret). Auth disabled (all requests allowed) when unset | ❌ | `a-long-random-secret` |
        | `CYBORGDB_DB_TYPE` | Storage backend (`disk`, `s3`) | ❌ (defaults to `disk`) | `s3` |
        | `CYBORGDB_DISK_PATH` | Data directory for `disk` storage | ❌ | `/var/lib/cyborgdb` |
        | `CYBORGDB_S3_BUCKET` | Bucket name for `s3` storage | Required for S3 | `my-bucket` |
        | `CYBORGDB_S3_REGION` | Region for `s3` storage | ❌ | `us-east-1` |
        | `PORT` | Service port | ❌ | `8000` |
        | `SSL_CERT_PATH` | Path to SSL certificate file | ❌ | `/etc/ssl/certs/server.crt` |
        | `SSL_KEY_PATH` | Path to SSL private key file | ❌ | `/etc/ssl/private/server.key` |

        <Note>None of these are required — the container starts with no configuration, using `disk` storage rooted at `/app/cyborgdb_data`, free-tier licensing, and authentication disabled. For the full list (including S3 credentials and KMS), see the [Environment Variables](../advanced/env-vars) guide.</Note>
      </Tab>

      <Tab title="HTTPS Configuration">
        For production deployments, configure HTTPS by providing SSL certificates:

        **Environment Variables:**

        ```bash theme={null}
        SSL_CERT_PATH=/path/to/certificate.crt
        SSL_KEY_PATH=/path/to/private.key
        ```

        **Docker Run Example:**

        ```bash theme={null}
        docker run -it -p 8000:8000 \
          -e CYBORGDB_API_KEY=cyborg_your_api_key_here \
          -e CYBORGDB_DB_TYPE=s3 \
          -e CYBORGDB_S3_BUCKET=cyborgdb-prod \
          -e CYBORGDB_S3_REGION=us-east-1 \
          -e SSL_CERT_PATH=/certs/server.crt \
          -e SSL_KEY_PATH=/certs/server.key \
          -v /host/path/to/certs:/certs \
          cyborginc/cyborgdb-service:latest
        ```

        **Docker Compose with SSL:**

        ```yaml theme={null}
        services:
          cyborgdb:
            image: cyborginc/cyborgdb-service:latest
            ports:
              - "8000:8000"
            environment:
              - CYBORGDB_API_KEY=cyborg_your_api_key_here
              - CYBORGDB_DB_TYPE=s3
              - CYBORGDB_S3_BUCKET=cyborgdb-prod
              - CYBORGDB_S3_REGION=us-east-1
              - SSL_CERT_PATH=/certs/server.crt
              - SSL_KEY_PATH=/certs/server.key
            volumes:
              - ./certs:/certs
        ```

        <Note>The server automatically switches to HTTPS when both certificate files are provided and exist. Without certificates, it starts in HTTP mode.</Note>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Next Steps">
    The Python client above is the fastest way to reach a first query. To integrate from another language, install the equivalent client SDK:

    <CodeGroup>
      ```bash JavaScript icon="js" theme={null}
      npm install cyborgdb
      ```

      ```bash TypeScript icon="code" theme={null}
      npm install cyborgdb
      ```

      ```bash Go icon="golang" theme={null}
      go get github.com/cyborginc/cyborgdb-go
      ```
    </CodeGroup>

    <CardGroup cols={2}>
      <Card title="REST API Reference" href="../../rest-api/introduction" icon="rectangle-terminal">
        Learn how to use the REST API for direct integration
      </Card>

      <Card title="Python SDK Reference" href="../../python-sdk/introduction" icon="python">
        Learn how to use the Python SDK for direct integration
      </Card>

      <Card title="JS/TS SDK Reference" href="../../js-ts-sdk/introduction" icon="js">
        Learn how to use the JavaScript/TypeScript SDK for direct integration
      </Card>

      <Card title="Go SDK Reference" href="../../go-sdk/introduction" icon="golang">
        Learn how to use the Go SDK for direct integration
      </Card>
    </CardGroup>
  </Step>
</Steps>

<Accordion title="Technical Specifications">
  * **Base Image**: `python:3.14-slim`
  * **Python Version**: 3.14
  * **Docker Image Size**: about 124 MB compressed (no PyTorch bundled; see the Docker Hub page for the current size)
  * **Platform**: linux/amd64, linux/arm64
  * **Default Port**: 8000
</Accordion>

<Accordion title="Comparison with Python Service">
  | Aspect | Python Service | Docker Service |
  | - | - | - |
  | **Installation** | `pip install` | `docker run` |
  | **Dependencies** | Managed by pip/conda | Bundled in container |
  | **Resource Usage** | Lower overhead | Higher overhead |
  | **Environment Isolation** | Python virtualenv | Container isolation |
  | **Deployment Complexity** | Simple Python deployment | Container orchestration |
  | **Configuration** | Environment variables/files | Environment variables |
  | **Best For** | Development, Python-heavy workflows | Production, cloud deployment |

  <Tip>Both approaches provide identical CyborgDB functionality. Choose based on your deployment preferences and infrastructure requirements.</Tip>
</Accordion>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.