Docker Deployment
ByteBrew Engine ships as a single Docker image that pairs with PostgreSQL. This guide covers the complete Docker Compose setup from scratch.
Docker Compose setup
Section titled “Docker Compose setup”Create a docker-compose.yml file:
services: engine: image: bytebrew/engine:latest ports: - "${ENGINE_PORT:-8443}:8443" environment: - DATABASE_URL=postgresql://bytebrew:${POSTGRES_PASSWORD:-bytebrew}@db:5432/bytebrew - BYTEBREW_AUTH_MODE=${BYTEBREW_AUTH_MODE:-local} - BYTEBREW_JWT_KEYS_DIR=/var/lib/bytebrew/keys depends_on: db-migrate: condition: service_completed_successfully volumes: - keys-data:/var/lib/bytebrew/keys restart: unless-stopped healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://localhost:8443/api/v1/health"] interval: 10s timeout: 5s retries: 3 start_period: 20s
db-migrate: image: bytebrew/engine-migrations:latest depends_on: db: condition: service_healthy environment: - LIQUIBASE_COMMAND_URL=jdbc:postgresql://db:5432/bytebrew - LIQUIBASE_COMMAND_USERNAME=bytebrew - LIQUIBASE_COMMAND_PASSWORD=${POSTGRES_PASSWORD:-bytebrew} - LIQUIBASE_COMMAND_CHANGELOG_FILE=migrations/db.changelog-master.yaml command: update restart: "no"
db: image: pgvector/pgvector:pg16 environment: POSTGRES_USER: bytebrew POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-bytebrew} POSTGRES_DB: bytebrew volumes: - pg-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U bytebrew -d bytebrew"] interval: 5s timeout: 5s retries: 5 restart: unless-stopped
volumes: pg-data: keys-data:Create a .env file alongside it:
# Authentication (required)BYTEBREW_AUTH_MODE=local # or 'external'POSTGRES_PASSWORD=bytebrew
# OptionalENGINE_PORT=8443After starting, access the Admin Dashboard:
# Log in with your initial admin credentials (create account on first login)Start everything:
docker compose up -dVerify:
curl http://localhost:8443/api/v1/health# {"status":"ok","version":"1.0.0","agents_count":0}Environment variables
Section titled “Environment variables”| Variable | Required | Description |
|---|---|---|
DATABASE_URL | Yes | PostgreSQL connection string. The compose file sets this automatically. |
BYTEBREW_AUTH_MODE | Yes | Auth mode: local (default, single-node) or external (multi-replica). |
BYTEBREW_JWT_KEYS_DIR | No | Directory for Ed25519 keypair storage (local mode only). Default: /var/lib/bytebrew/keys. |
BYTEBREW_JWT_PUBLIC_KEY_PATH | No | Path to public key file (external mode only). |
LLM_API_KEY | No | Default API key referenced as ${LLM_API_KEY} in agent configs. |
POSTGRES_PASSWORD | No | PostgreSQL password. Default: bytebrew. |
ENGINE_PORT | No | HTTP port for the REST API and Admin Dashboard. Default: 8443. |
Understanding host.docker.internal
Section titled “Understanding host.docker.internal”When the engine runs inside Docker but your LLM (e.g., Ollama) runs on the host machine, the engine cannot reach localhost because localhost inside a container refers to the container itself.
Use host.docker.internal instead:
models: llama-local: provider: ollama model: llama3.2 base_url: "http://host.docker.internal:11434/v1" api_key: "ollama"| Platform | host.docker.internal support |
|---|---|
| Docker Desktop (macOS, Windows) | Built-in, works automatically. |
| Linux (Docker Engine) | Add extra_hosts: ["host.docker.internal:host-gateway"] to the engine service in docker-compose.yml. |
Linux example:
services: engine: image: bytebrew/engine:latest extra_hosts: - "host.docker.internal:host-gateway" # ... rest of configVolumes and data persistence
Section titled “Volumes and data persistence”| Volume/Mount | Purpose |
|---|---|
pg-data (named volume) | PostgreSQL database files. All agent configs, sessions, tasks, audit logs, and memories. Back this up regularly. |
./agents.yaml (optional bind mount) | Bootstrap configuration file. Mount read-only for GitOps workflows. Not needed when using Admin Dashboard. |
Port mapping
Section titled “Port mapping”| Port | Service |
|---|---|
8443 | REST API and Admin Dashboard (Docker Compose default) |
The engine serves everything on a single port. For production, put a reverse proxy (Caddy, nginx) in front for TLS. See Production deployment.
Troubleshooting
Section titled “Troubleshooting””model requires more memory”
Section titled “”model requires more memory””The LLM provider returned an out-of-memory error. This happens with large models on Ollama:
- Use a smaller model (llama3.2 3B instead of 70B).
- Increase Docker memory limits in Docker Desktop settings.
- If using Ollama, ensure the host machine has enough VRAM. Check with
nvidia-smi.
Port conflicts
Section titled “Port conflicts”If port 8443 is already in use:
# Change the host-side port (left of the colon)ports: - "9443:8443" # Accessible at localhost:9443pgvector extension errors
Section titled “pgvector extension errors”ByteBrew requires the pgvector extension for knowledge base embeddings. The pgvector/pgvector:pg16 image includes it pre-installed. If you use a plain PostgreSQL image, install pgvector manually:
CREATE EXTENSION IF NOT EXISTS vector;Engine cannot reach Ollama on the host
Section titled “Engine cannot reach Ollama on the host”See the host.docker.internal section above. On Linux, you must add extra_hosts to the compose file.
Container keeps restarting
Section titled “Container keeps restarting”Check logs:
docker compose logs engine --tail 50Common causes:
DATABASE_URLis wrong or PostgreSQL is not ready yet (thedepends_onwith healthcheck should handle this).- Invalid
agents.yamlsyntax. - Missing environment variables referenced in YAML (
${VAR}that is not set).
Upgrading
Section titled “Upgrading”Pull the latest image and restart:
docker compose pulldocker compose up -dThe db-migrate service applies any new Liquibase changesets before the engine starts. Your data and configuration are preserved.