Skip to main content

Docker Deployment

For Platform Teams

This guide covers deploying Olytix Core using Docker containers, from simple single-container setups to production-ready multi-service deployments with Docker Compose.

Prerequisites

  • Docker 20.10 or later
  • Docker Compose 2.0 or later (for multi-service deployments)
  • 4 GB RAM minimum (8 GB recommended)
# Verify Docker installation
docker --version
docker compose version

Quick Start

Single Container

The simplest way to run Olytix Core:

# Pull the official image
docker pull olytix/olytix-core:latest

# Run Olytix Core with a local project
docker run -it --rm \
-v $(pwd)/my-project:/workspace \
-p 8000:8000 \
olytix/olytix-core:latest

# Access the API
curl http://localhost:8000/health/ready

With Environment Configuration

docker run -d \
--name olytix-core \
-v $(pwd)/project:/workspace \
-p 8000:8000 \
-e OLYTIX_LOG_LEVEL=INFO \
-e OLYTIX_DATABASE__HOST=host.docker.internal \
-e OLYTIX_DATABASE__PORT=5432 \
-e OLYTIX_DATABASE__USER=analytics \
-e OLYTIX_DATABASE__PASSWORD=secret \
olytix/olytix-core:latest

Dockerfile Reference

Official Image

The official olytix/olytix-core image is based on Python 3.12 slim and includes all dependencies.

Custom Dockerfile

For custom builds or additional dependencies:

# Dockerfile
FROM python:3.12-slim AS base

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PYTHONFAULTHANDLER=1 \
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1

# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
curl \
git \
&& rm -rf /var/lib/apt/lists/*

# Create non-root user
RUN useradd --create-home --shell /bin/bash olytix-core
WORKDIR /app

# Install Python dependencies
FROM base AS dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Production image
FROM base AS production
COPY --from=dependencies /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --from=dependencies /usr/local/bin /usr/local/bin

# Copy application
COPY --chown=olytix-core:olytix-core . .

# Switch to non-root user
USER olytix-core

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health/live || exit 1

# Expose port
EXPOSE 8000

# Start server
CMD ["uvicorn", "src.olytix-core.api.app:create_app", "--factory", "--host", "0.0.0.0", "--port", "8000"]

Multi-Stage Build for Smaller Images

# Dockerfile.production
FROM python:3.12-slim AS builder

WORKDIR /app
COPY requirements.txt .
RUN pip wheel --no-cache-dir --wheel-dir /wheels -r requirements.txt

FROM python:3.12-slim AS runtime

# Install only runtime dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
libpq5 \
curl \
&& rm -rf /var/lib/apt/lists/*

# Create non-root user
RUN useradd --create-home olytix-core
WORKDIR /app

# Copy wheels and install
COPY --from=builder /wheels /wheels
RUN pip install --no-cache-dir /wheels/* && rm -rf /wheels

# Copy application code
COPY --chown=olytix-core:olytix-core src/ ./src/
COPY --chown=olytix-core:olytix-core pyproject.toml .

# Install application
RUN pip install --no-cache-dir -e .

USER olytix-core
EXPOSE 8000

CMD ["uvicorn", "src.olytix-core.api.app:create_app", "--factory", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]

Docker Compose

Development Environment

# docker-compose.yml
version: '3.8'

services:
olytix-core:
image: olytix/olytix-core:latest
container_name: olytix-core-api
ports:
- "8000:8000"
volumes:
- ./project:/workspace
- ./logs:/app/logs
environment:
- OLYTIX_LOG_LEVEL=DEBUG
- OLYTIX_DATABASE__HOST=postgres
- OLYTIX_DATABASE__PORT=5432
- OLYTIX_DATABASE__USER=olytix-core
- OLYTIX_DATABASE__PASSWORD=olytix-core_secret
- OLYTIX_DATABASE__NAME=analytics
- OLYTIX_REDIS__URL=redis://redis:6379/0
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health/ready"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s

postgres:
image: postgres:15-alpine
container_name: olytix-core-postgres
environment:
POSTGRES_USER: olytix-core
POSTGRES_PASSWORD: olytix-core_secret
POSTGRES_DB: analytics
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init-db:/docker-entrypoint-initdb.d
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U olytix-core -d analytics"]
interval: 10s
timeout: 5s
retries: 5

redis:
image: redis:7-alpine
container_name: olytix-core-redis
command: redis-server --appendonly yes
volumes:
- redis_data:/data
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5

volumes:
postgres_data:
redis_data:

Production Environment

# docker-compose.prod.yml
version: '3.8'

services:
olytix-core-api:
image: olytix/olytix-core:${OLYTIX_VERSION:-latest}
deploy:
replicas: 2
resources:
limits:
cpus: '2'
memory: 4G
reservations:
cpus: '1'
memory: 2G
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
ports:
- "8000:8000"
volumes:
- ./project:/workspace:ro
environment:
- OLYTIX_LOG_LEVEL=INFO
- OLYTIX_LOG_FORMAT=json
- OLYTIX_DATABASE__HOST=${DB_HOST}
- OLYTIX_DATABASE__PORT=${DB_PORT:-5432}
- OLYTIX_DATABASE__USER=${DB_USER}
- OLYTIX_DATABASE__PASSWORD=${DB_PASSWORD}
- OLYTIX_DATABASE__NAME=${DB_NAME}
- OLYTIX_REDIS__URL=${REDIS_URL}
- OLYTIX_SERVER__WORKERS=4
- OLYTIX_METRICS__ENABLED=true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health/ready"]
interval: 30s
timeout: 10s
retries: 3
networks:
- olytix-core-network

olytix-core-worker:
image: olytix/olytix-core:${OLYTIX_VERSION:-latest}
command: celery -A src.olytix-core.tasks worker --loglevel=info --concurrency=4
deploy:
replicas: 2
resources:
limits:
cpus: '2'
memory: 4G
environment:
- OLYTIX_LOG_LEVEL=INFO
- OLYTIX_LOG_FORMAT=json
- OLYTIX_DATABASE__HOST=${DB_HOST}
- OLYTIX_DATABASE__PORT=${DB_PORT:-5432}
- OLYTIX_DATABASE__USER=${DB_USER}
- OLYTIX_DATABASE__PASSWORD=${DB_PASSWORD}
- OLYTIX_DATABASE__NAME=${DB_NAME}
- OLYTIX_REDIS__URL=${REDIS_URL}
depends_on:
- olytix-core-api
networks:
- olytix-core-network

olytix-core-scheduler:
image: olytix/olytix-core:${OLYTIX_VERSION:-latest}
command: celery -A src.olytix-core.tasks beat --loglevel=info
deploy:
replicas: 1
environment:
- OLYTIX_LOG_LEVEL=INFO
- OLYTIX_REDIS__URL=${REDIS_URL}
depends_on:
- olytix-core-worker
networks:
- olytix-core-network

nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
depends_on:
- olytix-core-api
networks:
- olytix-core-network

networks:
olytix-core-network:
driver: bridge

Nginx Configuration

# nginx.conf
events {
worker_connections 1024;
}

http {
upstream olytix-core_api {
least_conn;
server olytix-core-api:8000;
}

server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}

server {
listen 443 ssl http2;
server_name _;

ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;

# Security headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

location / {
proxy_pass http://olytix-core_api;
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;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
}

location /health {
proxy_pass http://olytix-core_api;
access_log off;
}
}
}

Environment Variables

Create a .env file for sensitive configuration:

# .env
# Database
DB_HOST=postgres.example.com
DB_PORT=5432
DB_USER=olytix-core_prod
DB_PASSWORD=your_secure_password
DB_NAME=olytix-core_analytics

# Redis
REDIS_URL=redis://:redis_password@redis.example.com:6379/0

# Olytix Core Version
OLYTIX_VERSION=1.2.0

# API Keys
OLYTIX_API_KEY=your_api_key
OLYTIX_SECRET_KEY=your_secret_key

Running Commands

Start Services

# Development
docker compose up -d

# Production
docker compose -f docker-compose.prod.yml up -d

# View logs
docker compose logs -f olytix-core

# Scale workers
docker compose -f docker-compose.prod.yml up -d --scale olytix-core-worker=4

Maintenance Operations

# Run migrations
docker compose exec olytix-core olytix-core migrate --apply

# Compile project
docker compose exec olytix-core olytix-core compile

# Access shell
docker compose exec olytix-core bash

# View running containers
docker compose ps

Shutdown

# Stop services
docker compose down

# Stop and remove volumes (WARNING: deletes data)
docker compose down -v

Health Checks

Olytix Core exposes health check endpoints:

# Liveness - is the process running?
curl http://localhost:8000/health/live

# Readiness - is the service ready to accept traffic?
curl http://localhost:8000/health/ready

# Detailed status
curl http://localhost:8000/health/status

Example response:

{
"status": "healthy",
"version": "1.2.0",
"checks": {
"database": "ok",
"redis": "ok",
"warehouse": "ok"
},
"uptime_seconds": 3600
}

Troubleshooting

Container Fails to Start

# Check logs
docker logs olytix-core-api

# Common issues:
# - Database connection refused: Check DB_HOST and network
# - Permission denied: Check volume mount permissions
# - Port already in use: Change port mapping

Performance Issues

# Check resource usage
docker stats

# Increase memory limits
docker compose up -d --scale olytix-core-api=2

Network Connectivity

# Test database connection from container
docker compose exec olytix-core nc -zv postgres 5432

# Check DNS resolution
docker compose exec olytix-core nslookup postgres

Next Steps