Skip to main content

Overview

This guide covers deploying Sonore Phone Agent using Docker containers. While the project doesn’t include a pre-built Dockerfile, this guide provides production-ready configurations based on the application’s architecture.

Docker Configuration

Creating a Dockerfile

Create a Dockerfile in the project root:
# Use Python 3.12 slim image
FROM python:3.12-slim

# Set working directory
WORKDIR /app

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

# Install uv package manager
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
ENV PATH="/root/.cargo/bin:$PATH"

# Copy project files
COPY pyproject.toml .
COPY requirements.txt .

# Install dependencies
RUN uv sync --no-dev

# Copy application source
COPY src/ ./src/
COPY data/ ./data/
COPY start.sh ./
COPY start_call.sh ./
COPY start_postcall.sh ./

# Make scripts executable
RUN chmod +x start.sh start_call.sh start_postcall.sh

# Expose ports
EXPOSE 8000 8001

# Set environment variables
ENV PORT=8000
ENV POSTCALL_PORT=8001
ENV PYTHONUNBUFFERED=1

# Run the application
CMD ["./start.sh"]

Multi-Service Deployment

For production deployments, consider separate containers for each service:
# Calls service container
FROM python:3.12-slim

WORKDIR /app

RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
ENV PATH="/root/.cargo/bin:$PATH"

COPY pyproject.toml requirements.txt ./
RUN uv sync --no-dev

COPY src/ ./src/
COPY data/ ./data/
COPY start_call.sh ./
RUN chmod +x start_call.sh

EXPOSE 8000
ENV PORT=8000
ENV PYTHONUNBUFFERED=1

CMD ["./start_call.sh"]

Docker Compose Setup

Basic Configuration

Create a docker-compose.yml file:
version: '3.8'

services:
  mongodb:
    image: mongo:7
    restart: always
    ports:
      - "27017:27017"
    volumes:
      - mongodb_data:/data/db
    environment:
      - MONGO_INITDB_DATABASE=sonore_phone_agent
    healthcheck:
      test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet
      interval: 10s
      timeout: 5s
      retries: 5

  calls:
    build:
      context: .
      dockerfile: Dockerfile.calls
    restart: always
    ports:
      - "8000:8000"
    env_file:
      - .env
    environment:
      - PORT=8000
      - MONGODB_URI=mongodb://mongodb:27017
      - POST_CALL_URI=http://postcall:8001
    depends_on:
      mongodb:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  postcall:
    build:
      context: .
      dockerfile: Dockerfile.postcall
    restart: always
    ports:
      - "8001:8001"
    env_file:
      - .env
    environment:
      - PORT=8001
      - MONGODB_URI=mongodb://mongodb:27017
    depends_on:
      mongodb:
        condition: service_healthy

volumes:
  mongodb_data:

Production Configuration

For production deployments, enhance the configuration with:
version: '3.8'

services:
  mongodb:
    image: mongo:7
    restart: always
    volumes:
      - mongodb_data:/data/db
      - ./mongo-init:/docker-entrypoint-initdb.d
    environment:
      - MONGO_INITDB_ROOT_USERNAME=${MONGO_ROOT_USER}
      - MONGO_INITDB_ROOT_PASSWORD=${MONGO_ROOT_PASSWORD}
      - MONGO_INITDB_DATABASE=sonore_phone_agent
    networks:
      - internal
    # No external port exposure for security

  calls:
    build:
      context: .
      dockerfile: Dockerfile.calls
    restart: always
    ports:
      - "8000:8000"
    env_file:
      - .env.production
    environment:
      - PORT=8000
      - MONGODB_URI=mongodb://${MONGO_USER}:${MONGO_PASSWORD}@mongodb:27017/sonore_phone_agent?authSource=admin
      - POST_CALL_URI=http://postcall:8001
      - LOG_LEVEL=INFO
    depends_on:
      mongodb:
        condition: service_healthy
    networks:
      - internal
      - external
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      replicas: 2
      resources:
        limits:
          cpus: '1'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M

  postcall:
    build:
      context: .
      dockerfile: Dockerfile.postcall
    restart: always
    env_file:
      - .env.production
    environment:
      - PORT=8001
      - MONGODB_URI=mongodb://${MONGO_USER}:${MONGO_PASSWORD}@mongodb:27017/sonore_phone_agent?authSource=admin
      - LOG_LEVEL=INFO
    depends_on:
      mongodb:
        condition: service_healthy
    networks:
      - internal
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

  nginx:
    image: nginx:alpine
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - calls
    networks:
      - external
      - internal

networks:
  internal:
    driver: bridge
  external:
    driver: bridge

volumes:
  mongodb_data:

Running with Docker Compose

1

Build the images

docker-compose build
2

Start the services

docker-compose up -d
The -d flag runs containers in detached mode.
3

Verify services are running

docker-compose ps
Check the health status of all services:
docker-compose ps
curl http://localhost:8000/health
4

View logs

# All services
docker-compose logs -f

# Specific service
docker-compose logs -f calls
docker-compose logs -f postcall

Service Management

Common Commands

docker-compose stop

Updating the Application

1

Pull latest code

git pull origin main
2

Rebuild images

docker-compose build --no-cache
3

Restart services

docker-compose up -d
Docker Compose will recreate containers with the new images.

Environment Configuration

Startup Scripts

The application uses shell scripts for service orchestration: start.sh - Runs both services (source/start.sh:1):
  • Starts calls service on $PORT (default: 8000) bound to 0.0.0.0
  • Starts post-call service on $POSTCALL_PORT (default: 8001) bound to 127.0.0.1
  • Implements cleanup trap to terminate both processes on exit
  • Exits if either process terminates
start_call.sh - Runs calls service only (source/start_call.sh:1):
  • Binds to 0.0.0.0:$PORT for external access
  • Uses exec for proper signal handling
start_postcall.sh - Runs post-call service only (source/start_postcall.sh:1):
  • Binds to 0.0.0.0:$PORT (unlike start.sh which uses 127.0.0.1)
  • Intended for separate container deployment
When using start.sh, the post-call service is only accessible from localhost. For multi-container deployments, use separate startup scripts that bind to 0.0.0.0.

Security Best Practices

  • Use Docker networks to isolate services
  • Only expose the calls service publicly
  • Keep post-call service on internal network
  • Use nginx or a reverse proxy for SSL termination
Use Docker secrets or environment variable encryption:
# Using Docker secrets (Swarm mode)
echo "sk-your-api-key" | docker secret create openai_api_key -
Reference in docker-compose.yml:
services:
  calls:
    secrets:
      - openai_api_key
secrets:
  openai_api_key:
    external: true
Always set CPU and memory limits:
deploy:
  resources:
    limits:
      cpus: '1'
      memory: 1G
  • Use authentication for MongoDB
  • Don’t expose MongoDB port externally
  • Use encrypted connections (TLS/SSL)
  • Regular backups of MongoDB volumes

Troubleshooting

Check logs for errors:
docker-compose logs calls
Common issues:
  • Missing environment variables
  • MongoDB connection failure
  • Port conflicts
Ensure MongoDB is healthy:
docker-compose exec mongodb mongosh --eval "db.adminCommand('ping')"
Check network connectivity:
docker-compose exec calls ping mongodb
Monitor container resources:
docker stats
Adjust resource limits or scale horizontally.
Verify services are on the same network:
docker network inspect sonore-phone-agent_internal
Check service discovery:
docker-compose exec calls ping postcall

Next Steps

Monitoring

Set up logging and metrics collection

API Reference

Explore the API endpoints

Build docs developers (and LLMs) love