Skip to main content

Docker Deployment

Deploy Parallax using Docker containers for consistent, reproducible environments.

Quick Start

Pull the Image

docker pull parallax/control-plane:latest

Run the Control Plane

docker run -d \
--name parallax \
-p 8080:8080 \
parallax/control-plane:latest

Verify It's Running

curl http://localhost:8080/health

Expected response:

{
"status": "healthy",
"version": "1.0.0",
"uptime": 42
}

Docker Compose

Basic Setup

Create docker-compose.yaml:

version: '3.8'

services:
control-plane:
image: parallax/control-plane:latest
ports:
- "8080:8080"
environment:
- PARALLAX_LOG_LEVEL=info
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
timeout: 5s
retries: 3

Start the service:

docker compose up -d

With Persistence

version: '3.8'

services:
control-plane:
image: parallax/control-plane:latest
ports:
- "8080:8080"
environment:
- PARALLAX_LOG_LEVEL=info
- PARALLAX_STORAGE_TYPE=sqlite
- PARALLAX_STORAGE_PATH=/data/parallax.db
volumes:
- parallax-data:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
timeout: 5s
retries: 3

volumes:
parallax-data:

With Redis (for HA)

version: '3.8'

services:
control-plane:
image: parallax/control-plane:latest
ports:
- "8080:8080"
environment:
- PARALLAX_LOG_LEVEL=info
- PARALLAX_REDIS_URL=redis://redis:6379
depends_on:
- redis
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
timeout: 5s
retries: 3

redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis-data:/data
command: redis-server --appendonly yes

volumes:
redis-data:

Full Stack (Control Plane + Agents)

version: '3.8'

services:
control-plane:
image: parallax/control-plane:latest
ports:
- "8080:8080"
environment:
- PARALLAX_LOG_LEVEL=info
- PARALLAX_REDIS_URL=redis://redis:6379
depends_on:
- redis
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
timeout: 5s
retries: 3

agent-classification:
image: parallax/agent:latest
environment:
- PARALLAX_CONTROL_PLANE_URL=http://control-plane:8080
- AGENT_CAPABILITIES=classification
- OPENAI_API_KEY=${OPENAI_API_KEY}
depends_on:
- control-plane
deploy:
replicas: 3

agent-analysis:
image: parallax/agent:latest
environment:
- PARALLAX_CONTROL_PLANE_URL=http://control-plane:8080
- AGENT_CAPABILITIES=analysis,summarization
- OPENAI_API_KEY=${OPENAI_API_KEY}
depends_on:
- control-plane
deploy:
replicas: 3

redis:
image: redis:7-alpine
volumes:
- redis-data:/data
command: redis-server --appendonly yes

volumes:
redis-data:

Configuration

Environment Variables

VariableDescriptionDefault
PARALLAX_PORTHTTP/WebSocket port8080
PARALLAX_HOSTBind address0.0.0.0
PARALLAX_LOG_LEVELLog levelinfo
PARALLAX_LOG_FORMATLog format (json, text)json
PARALLAX_STORAGE_TYPEStorage backendmemory
PARALLAX_STORAGE_PATHFile/SQLite path-
PARALLAX_REDIS_URLRedis connection URL-
PARALLAX_MAX_AGENTSMax agent connections1000
PARALLAX_EXECUTION_TIMEOUTDefault timeout (ms)30000

Configuration File

Mount a configuration file:

services:
control-plane:
image: parallax/control-plane:latest
volumes:
- ./parallax.config.yaml:/etc/parallax/config.yaml:ro
environment:
- PARALLAX_CONFIG=/etc/parallax/config.yaml

Example parallax.config.yaml:

server:
port: 8080
host: 0.0.0.0

logging:
level: info
format: json

storage:
type: sqlite
path: /data/parallax.db

execution:
defaultTimeout: 30000
maxConcurrentExecutions: 100

agents:
maxConnections: 1000
heartbeatInterval: 10000
reconnectTimeout: 30000

patterns:
autoReload: true
directory: /patterns

Mount Patterns Directory

services:
control-plane:
image: parallax/control-plane:latest
volumes:
- ./patterns:/patterns:ro
environment:
- PARALLAX_PATTERNS_DIR=/patterns
- PARALLAX_PATTERNS_AUTO_RELOAD=true

Building Custom Images

Custom Control Plane

# Dockerfile.control-plane
FROM parallax/control-plane:latest

# Add custom patterns
COPY patterns/ /patterns/

# Add custom configuration
COPY parallax.config.yaml /etc/parallax/config.yaml

ENV PARALLAX_CONFIG=/etc/parallax/config.yaml
ENV PARALLAX_PATTERNS_DIR=/patterns

Build and run:

docker build -f Dockerfile.control-plane -t my-parallax:latest .
docker run -d -p 8080:8080 my-parallax:latest

Custom Agent

# Dockerfile.agent
FROM node:20-slim

WORKDIR /app

# Install dependencies
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm install --frozen-lockfile

# Copy agent code
COPY agent.ts ./
COPY tsconfig.json ./

# Build
RUN pnpm build

# Run
CMD ["node", "dist/agent.js"]

Example agent.ts:

import { ParallaxAgent } from '@parallax/sdk-typescript';

const agent = new ParallaxAgent({
controlPlaneUrl: process.env.PARALLAX_CONTROL_PLANE_URL!,
capabilities: process.env.AGENT_CAPABILITIES?.split(',') || [],
});

agent.onTask('classification', async (task) => {
// Your logic here
return { category: 'result', confidence: 0.9 };
});

agent.connect();
console.log('Agent connected');

Networking

Bridge Network (Default)

Services communicate via container names:

services:
control-plane:
networks:
- parallax-net

agent:
environment:
- PARALLAX_CONTROL_PLANE_URL=http://control-plane:8080
networks:
- parallax-net

networks:
parallax-net:
driver: bridge

Host Network

For performance-sensitive deployments:

services:
control-plane:
network_mode: host
environment:
- PARALLAX_PORT=8080

External Access

Expose via reverse proxy:

services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
depends_on:
- control-plane

control-plane:
image: parallax/control-plane:latest
# Not exposed directly

Example nginx.conf:

upstream parallax {
server control-plane:8080;
}

server {
listen 80;
server_name parallax.example.com;
return 301 https://$server_name$request_uri;
}

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

ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;

location / {
proxy_pass http://parallax;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

Health Checks

Control Plane Health

healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
timeout: 5s
retries: 3
start_period: 10s

Health Endpoints

EndpointDescription
/healthBasic health check
/health/readyReadiness probe (for load balancers)
/health/liveLiveness probe (for orchestrators)

Detailed Health Response

curl http://localhost:8080/health?detailed=true
{
"status": "healthy",
"version": "1.0.0",
"uptime": 3600,
"components": {
"storage": "healthy",
"redis": "healthy",
"agents": {
"connected": 9,
"healthy": 9
}
},
"metrics": {
"executionsTotal": 1234,
"executionsActive": 5,
"avgExecutionTime": 2340
}
}

Logging

Log Configuration

environment:
- PARALLAX_LOG_LEVEL=info
- PARALLAX_LOG_FORMAT=json

View Logs

# Follow logs
docker compose logs -f control-plane

# Last 100 lines
docker compose logs --tail 100 control-plane

# Filter by time
docker compose logs --since 1h control-plane

Log Output (JSON)

{"timestamp":"2024-01-15T10:30:00Z","level":"info","message":"Execution started","executionId":"exec_abc123","pattern":"classifier"}
{"timestamp":"2024-01-15T10:30:01Z","level":"debug","message":"Agent selected","agentId":"agent_1","capabilities":["classification"]}
{"timestamp":"2024-01-15T10:30:02Z","level":"info","message":"Execution completed","executionId":"exec_abc123","duration":2340}

Log Aggregation

Send logs to centralized logging:

services:
control-plane:
logging:
driver: "fluentd"
options:
fluentd-address: "localhost:24224"
tag: "parallax.control-plane"

Resource Limits

Memory and CPU

services:
control-plane:
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
ComponentMin CPUMin MemoryRecommended
Control Plane0.5512MB2 CPU, 2GB
Agent0.25256MB1 CPU, 1GB
Redis0.25256MB1 CPU, 1GB

Scaling

Scale Agents

# Scale to 5 agent instances
docker compose up -d --scale agent-classification=5

Auto-Scaling with Docker Swarm

services:
agent:
deploy:
mode: replicated
replicas: 3
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure

Security

Run as Non-Root

services:
control-plane:
user: "1000:1000"

Read-Only Filesystem

services:
control-plane:
read_only: true
tmpfs:
- /tmp
volumes:
- parallax-data:/data

Secrets Management

services:
agent:
secrets:
- openai_api_key
environment:
- OPENAI_API_KEY_FILE=/run/secrets/openai_api_key

secrets:
openai_api_key:
file: ./secrets/openai_api_key.txt

Troubleshooting

Container Won't Start

# Check logs
docker compose logs control-plane

# Check container status
docker compose ps

# Inspect container
docker inspect parallax-control-plane-1

Connection Refused

# Check container is running
docker compose ps

# Check port mapping
docker compose port control-plane 8080

# Check from inside container
docker compose exec control-plane curl localhost:8080/health

Out of Memory

# Check memory usage
docker stats

# Increase limits in docker-compose.yaml

Disk Full

# Check disk usage
docker system df

# Clean up
docker system prune -a

Next Steps