imas-codex

Container Setup

This document describes how to build, run, and deploy the IMAS Codex containers.

Neo4j Knowledge Graph

The project uses Neo4j for the knowledge graph. Choose one of these deployment options:

Option 1: Docker Compose (if Docker available)

# Start Neo4j with the graph profile
docker-compose --profile graph up -d neo4j

# Verify it's running
curl -s http://localhost:7474

Option 2: Apptainer (for WSL, HPC, or systems without Docker)

Apptainer (formerly Singularity) is ideal for environments where Docker isn’t available.

# Install Apptainer (requires sudo)
./scripts/install_apptainer.sh

# Set up Neo4j container and systemd service
./scripts/setup_neo4j_apptainer.sh --system

# Start the service
sudo systemctl start imas-codex-neo4j.service

# Verify it's running
curl -s http://localhost:7474

Configuration options (environment variables for setup_neo4j_apptainer.sh):

Variable Default Description
NEO4J_VERSION 2025.11-community Neo4j Docker image tag
NEO4J_PASSWORD imas-codex Neo4j password
NEO4J_DATA_DIR ~/.local/share/imas-codex/neo4j Data directory
NEO4J_SIF_DIR ~/apptainer Container image location

Service management:

# Check status
sudo systemctl status imas-codex-neo4j.service

# Stop/Start/Restart
sudo systemctl stop imas-codex-neo4j.service
sudo systemctl start imas-codex-neo4j.service
sudo systemctl restart imas-codex-neo4j.service

# View logs
cat ~/.local/share/imas-codex/neo4j/logs/neo4j.log | tail -50

# Browser UI: http://localhost:7474
# Credentials: neo4j / imas-codex

IMAS Codex Server

Quick Start

# Build and run the container
docker-compose up -d

# View logs
docker-compose logs -f imas-codex

# Stop the container
docker-compose down

Using Docker directly

# Build the image
docker build -t imas-codex .

# Run the container
docker run -d \
  --name imas-codex \
  -p 8000:8000 \
  -v ./index:/app/index:ro \
  imas-codex

GitHub Container Registry

The container is automatically built and pushed to GitHub Container Registry on tagged releases.

Pull from GitHub Container Registry

# Pull the latest image
docker pull ghcr.io/iterorganization/imas-codex:latest

# Pull a specific version
docker pull ghcr.io/iterorganization/imas-codex:v1.0.0

# Run the pulled image
docker run -d \
  --name imas-codex \
  -p 8000:8000 \
  ghcr.io/iterorganization/imas-codex:latest

Available Tags

Environment Variables

Variable Description Default
PYTHONPATH Python path /app
PORT Port to run the server on 8000

Volume Mounts

Path Description
/app/index Index files directory (mount as read-only)
/app/logs Application logs (optional)

Health Check

The container includes a health check that verifies the server is responding correctly. The server uses streamable-http transport by default, which exposes a dedicated health endpoint that checks both server availability and search index functionality. The server runs in stateful mode to support MCP sampling functionality:

# Check container health status
docker ps
# Look for "healthy" status in the STATUS column

# Manual health check using the dedicated endpoint
curl -f http://localhost:8000/health
# Example health response
{
  "status": "healthy",
  "service": "imas-codex-server",
  "version": "4.0.1.dev164",
  "index_stats": {
    "total_paths": 15420,
    "index_name": "lexicographic_4.0.1.dev164"
  },
  "transport": "streamable-http"
}

Health Check Configuration

The health check is configured in docker-compose.yml:

healthcheck:
  test:
    [
      "CMD",
      "python",
      "-c",
      "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')",
    ]
  interval: 30s # Check every 30 seconds
  timeout: 10s # 10 second timeout per check
  retries: 3 # Mark unhealthy after 3 consecutive failures
  start_period: 40s # Wait 40 seconds before starting checks

Note: The health endpoint is available when using streamable-http transport (default). For other transports (stdio, sse), the health check will verify port connectivity only.

Production Deployment

With Nginx Reverse Proxy

# Use the production profile
docker-compose --profile production up -d

This will start both the IMAS Codex Server and an Nginx reverse proxy.

Kubernetes Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: imas-codex
spec:
  replicas: 2
  selector:
    matchLabels:
      app: imas-codex
  template:
    metadata:
      labels:
        app: imas-codex
    spec:
      containers:
        - name: imas-codex
          image: ghcr.io/iterorganization/imas-codex:latest
          ports:
            - containerPort: 8000
          env:
            - name: PYTHONPATH
              value: "/app"
          volumeMounts:
            - name: index-data
              mountPath: /app/index
              readOnly: true
          livenessProbe:
            httpGet:
              path: /health
              port: 8000
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /health
              port: 8000
            initialDelaySeconds: 5
            periodSeconds: 5
      volumes:
        - name: index-data
          persistentVolumeClaim:
            claimName: imas-index-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: imas-codex-service
spec:
  selector:
    app: imas-codex
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8000
  type: LoadBalancer

Development

Building locally

# Build the image
docker build -t imas-codex:dev .

# Run with development settings
docker run -it --rm \
  -p 8000:8000 \
  -v $(pwd):/app \
  -e PYTHONPATH=/app \
  imas-codex:dev

Debugging

# Run with interactive shell
docker run -it --rm \
  -p 8000:8000 \
  -v $(pwd):/app \
  ghcr.io/iterorganization/imas-codex:latest \
  /bin/bash

# View logs
docker logs -f imas-codex

Troubleshooting

Common Issues

  1. Container fails to start

    • Check that port 8000 is available
    • Verify index files are properly mounted
    • Check logs: docker-compose logs imas-codex
  2. Index files not found

    • Ensure the index directory exists and contains the necessary files
    • Check volume mount permissions
    • Verify the index files were built correctly
  3. Memory issues

    • The container may need more memory for large indexes
    • Consider using Docker’s memory limits: --memory=2g

Performance Tuning

# Run with increased memory
docker run -d \
  --name imas-codex \
  --memory=2g \
  --cpus=2 \
  -p 8000:8000 \
  ghcr.io/iterorganization/imas-codex:latest

CI/CD Pipeline

The project includes GitHub Actions workflows for:

  1. Testing (.github/workflows/test.yml)

    • Runs on every push and PR
    • Executes linting, formatting, and tests
  2. Container Build (.github/workflows/docker-build-push.yml)

    • Builds and pushes containers to GHCR
    • Supports multi-architecture builds (amd64, arm64)
    • Runs on pushes to main and tagged releases
  3. Releases (.github/workflows/release.yml)

    • Creates GitHub releases for tagged versions
    • Builds and uploads Python packages

GitHub Secrets Configuration

The OPENAI_API_KEY secret is optional for Docker builds.

What runs locally (no API key needed):

What uses the API key (optional):

Fallback behavior without API key:

  1. Uses pre-cached labels from imas_codex/definitions/clusters/labels.json (version-controlled)
  2. Falls back to auto-generated labels from path names if no cache exists

Configuring the secret (optional):

  1. Repository Settings: Go to SettingsSecrets and variablesActions
  2. Add Secret: Create a new repository secret:
    • Name: OPENAI_API_KEY
    • Value: Your OpenRouter API key

Manual Docker Build:

# Build without API key (uses cached/fallback labels)
docker build -t imas-codex .

# Build with API key for fresh LLM-generated labels
docker build --secret id=OPENAI_API_KEY,env=OPENAI_API_KEY -t imas-codex .

# Build with minimal IDS for faster iteration
docker build --build-arg IDS_FILTER="equilibrium" -t imas-codex:test .

Security