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:
Dockerfile.calls
Dockerfile.postcall
# 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
Start the services
The -d flag runs containers in detached mode.
Verify services are running
Check the health status of all services: docker-compose ps
curl http://localhost:8000/health
View logs
# All services
docker-compose logs -f
# Specific service
docker-compose logs -f calls
docker-compose logs -f postcall
Service Management
Common Commands
Stop services
Restart services
Stop and remove containers
Remove volumes (data will be lost)
Scale a service
Updating the Application
Rebuild images
docker-compose build --no-cache
Restart services
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
MongoDB connection errors
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: Adjust resource limits or scale horizontally.
Service communication failures
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