Codumentor logo Codumentor

Production Deployment

This guide covers deploying Codumentor in a production environment, including reverse proxy configuration, service management, data management, and operational best practices.

Docker Image

The deployment image is built from the same backend Dockerfile as the development container, but with a different target. Development uses target: dev through docker-compose.dev.yml; production uses the runtime target, which builds the UI and Linux executable in intermediate stages and copies only the executable into the final image.

docker build -f deploy/Dockerfile.backend --target runtime -t codumentor:latest .

Run it with your config, API keys, and persistent data mounted from outside the image:

docker run --rm \
  --name codumentor \
  -p 127.0.0.1:2638:2638 \
  --env-file .env \
  -v "$(pwd)/codumentor.yaml:/app/codumentor.yaml:ro" \
  -v codumentor-data:/app/data \
  -v codumentor-logs:/app/logs \
  -v codumentor-repos:/app/repos \
  codumentor:latest

For Docker deployments, prefer absolute in-container paths in codumentor.yaml:

repos_dir: /app/repos

vector_db:
  path: /app/data/vector_db

agent:
  storage_dir: /app/data/agent_storage

logging:
  file: /app/logs/codumentor.log

The image runs as the non-root codumentor user, exposes port 2638, and defaults to:

/app/codumentor -c /app/codumentor.yaml api --host 0.0.0.0 --port 2638

For private Git repositories, mount SSH credentials or deploy keys as read-only files under /home/codumentor/.ssh.

Reverse Proxy

Codumentor should run behind a reverse proxy in production. Non-container deployments bind to 127.0.0.1:2638 by default. The Docker image binds to 0.0.0.0 inside the container, so keep the published port loopback-only unless another network boundary already protects it.

nginx Example

server {
    listen 443 ssl;
    server_name codumentor.example.com;

    ssl_certificate     /etc/ssl/certs/codumentor.pem;
    ssl_certificate_key /etc/ssl/private/codumentor.key;

    location / {
        proxy_pass http://127.0.0.1:2638;

        # Required for Server-Sent Events (SSE) streaming
        proxy_set_header X-Accel-Buffering no;
        proxy_set_header Connection keep-alive;
        proxy_buffering off;

        # Standard proxy headers
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Timeout for long-running agent conversations
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
    }
}

The SSE headers (X-Accel-Buffering: no, Connection: keep-alive, and proxy_buffering off) are essential. Without them, nginx buffers streaming responses and the web UI will not receive real-time updates.

Systemd Service

Create a systemd unit to manage the Codumentor API server as a background service.

Service Unit File

Create /etc/systemd/system/codumentor.service:

[Unit]
Description=Codumentor API Server
After=network.target

[Service]
Type=simple
User=codumentor
Group=codumentor
WorkingDirectory=/opt/codumentor
ExecStart=/opt/codumentor/.venv/bin/python -m codumentor.cli.main api
Restart=on-failure
RestartSec=5

# Environment variables for API keys (do not store in config files)
Environment="OPENAI_API_KEY=sk-..."
Environment="GOOGLE_API_KEY=..."
# Or load from an environment file:
# EnvironmentFile=/etc/codumentor/env

# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/opt/codumentor/data /opt/codumentor/logs

[Install]
WantedBy=multi-user.target

Managing the Service

# Reload after creating or editing the unit file
sudo systemctl daemon-reload

# Start the service
sudo systemctl start codumentor

# Enable start on boot
sudo systemctl enable codumentor

# Check status
sudo systemctl status codumentor

# View logs
sudo journalctl -u codumentor -f

Data Directories

Codumentor stores persistent data in the following directories. Ensure they exist and are writable by the service user before starting the application.

DirectoryPurposeDefault Path
data/vector_dbChromaDB vector database for indexed repository content./data/vector_db
data/agent_storageAgent conversation history and state./data/agent_storage
logs/Application log files./logs/
mkdir -p /opt/codumentor/data/vector_db
mkdir -p /opt/codumentor/data/agent_storage
mkdir -p /opt/codumentor/logs
chown -R codumentor:codumentor /opt/codumentor/data /opt/codumentor/logs

Backup Strategy

What to Back Up

  1. SQLite databases -- Agent storage contains conversation history and session data. Back up all .db files under data/agent_storage/.
  2. Vector database directory -- The entire data/vector_db/ directory contains indexed repository content. This can be rebuilt by re-running ingestion, but backing it up avoids downtime.
  3. Configuration files -- Back up codumentor.yaml and any extended config files.

Example Backup Script

#!/bin/bash
BACKUP_DIR="/backups/codumentor/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"

# Stop the service briefly for consistent SQLite backups
sudo systemctl stop codumentor

cp -r /opt/codumentor/data/agent_storage "$BACKUP_DIR/"
cp -r /opt/codumentor/data/vector_db "$BACKUP_DIR/"
cp /opt/codumentor/codumentor.yaml "$BACKUP_DIR/"

sudo systemctl start codumentor

For zero-downtime backups, use SQLite's .backup command or sqlite3 CLI to create consistent copies without stopping the service.

Environment Variables for Production

API keys and secrets must be provided through environment variables, not stored in configuration files. Use the ${VAR_NAME} substitution syntax in codumentor.yaml:

models:
  agent_api_key: "${OPENAI_API_KEY}"
  embedding_api_key: "${GOOGLE_API_KEY}"

auth:
  provider: ldap
  ldap:
    bind_password: "${LDAP_BIND_PASSWORD}"

Set the variables in the systemd EnvironmentFile, in your shell profile, or through your secrets manager. Never commit actual secret values to version control.

Logging in Production

JSON Logging

Enable structured JSON logging for integration with log aggregation systems (ELK, Splunk, Datadog):

logging:
  level: INFO
  file: ./logs/codumentor.log
  json_logging: true
  json_log_file: ./logs/codumentor.json.log

Each log entry is a single JSON line suitable for machine parsing:

{
  "timestamp": "2026-02-16T10:30:00.123",
  "level": "INFO",
  "logger": "codumentor.api",
  "message": "Request completed",
  "context": {
    "session_id": "abc123"
  }
}

Log Rotation

Configure log rotation to prevent log files from consuming all disk space. Example logrotate configuration at /etc/logrotate.d/codumentor:

/opt/codumentor/logs/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
}

See Also