#
Deployment Guide
Deploy Sonora in production environments.
#
Docker Deployment
#
Basic Setup
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
RUN pip install -e .
EXPOSE 8080
CMD ["python", "-m", "sonora.cli", "start"]
#
Multi-stage Build
# Build stage
FROM python:3.11 as builder
WORKDIR /app
COPY pyproject.toml .
RUN pip install build && python -m build
# Runtime stage
FROM python:3.11-slim as runtime
COPY --from=builder /app/dist/*.whl .
RUN pip install *.whl
CMD ["sonoractl", "start"]
#
Docker Compose
version: '3.8'
services:
sonora:
build: .
environment:
- LAVALINK_HOST=lavalink
- DISCORD_TOKEN=${DISCORD_TOKEN}
depends_on:
- lavalink
lavalink:
image: fredboat/lavalink:4.0.1
volumes:
- ./application.yml:/opt/Lavalink/application.yml
ports:
- "2333:2333"
#
Kubernetes Deployment
#
Deployment Manifest
apiVersion: apps/v1
kind: Deployment
metadata:
name: sonora
spec:
replicas: 3
selector:
matchLabels:
app: sonora
template:
metadata:
labels:
app: sonora
spec:
containers:
- name: sonora
image: code-xon/sonora:latest
env:
- name: LAVALINK_HOST
value: "lavalink-service"
- name: DISCORD_TOKEN
valueFrom:
secretKeyRef:
name: discord-secret
key: token
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
#
Service Configuration
apiVersion: v1
kind: Service
metadata:
name: sonora-service
spec:
selector:
app: sonora
ports:
- port: 80
targetPort: 8080
type: LoadBalancer
#
Cloud Deployment
#
AWS ECS
{
"family": "sonora-task",
"containerDefinitions": [
{
"name": "sonora",
"image": "code-xon/sonora:latest",
"essential": true,
"environment": [
{"name": "LAVALINK_HOST", "value": "lavalink.example.com"},
{"name": "DISCORD_TOKEN", "value": "${DISCORD_TOKEN}"}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/sonora",
"awslogs-region": "us-east-1"
}
}
}
]
}
#
Google Cloud Run
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: sonora
spec:
template:
spec:
containers:
- image: gcr.io/project/sonora:latest
env:
- name: LAVALINK_HOST
value: "lavalink.example.com"
- name: DISCORD_TOKEN
valueFrom:
secretKeyRef:
name: discord-token
key: latest
resources:
limits:
memory: "512Mi"
cpu: "1000m"
#
Configuration Management
#
Environment Variables
# Application config
export SONORA_ENV=production
export SONORA_DEBUG=false
export SONORA_LOG_LEVEL=INFO
# Lavalink config
export LAVALINK_HOST=lavalink.example.com
export LAVALINK_PORT=2333
export LAVALINK_PASSWORD=secure_password
# Discord config
export DISCORD_TOKEN=bot_token
export DISCORD_SHARD_COUNT=2
# Database config
export DATABASE_URL=postgresql://user:pass@host:5432/db
#
Configuration Files
# config.py
import os
config = {
'environment': os.getenv('SONORA_ENV', 'development'),
'debug': os.getenv('SONORA_DEBUG', 'false').lower() == 'true',
'lavalink': {
'host': os.getenv('LAVALINK_HOST', 'localhost'),
'port': int(os.getenv('LAVALINK_PORT', 2333)),
'password': os.getenv('LAVALINK_PASSWORD'),
},
'discord': {
'token': os.getenv('DISCORD_TOKEN'),
'shard_count': int(os.getenv('DISCORD_SHARD_COUNT', 1)),
},
'database': {
'url': os.getenv('DATABASE_URL'),
}
}
#
Monitoring & Logging
#
Structured Logging
import structlog
# Configure structured logging
structlog.configure(
processors=[
structlog.stdlib.filter_by_level,
structlog.stdlib.add_logger_name,
structlog.stdlib.add_log_level,
structlog.stdlib.PositionalArgumentsFormatter(),
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.StackInfoRenderer(),
structlog.processors.format_exc_info,
structlog.processors.UnicodeDecoder(),
structlog.processors.JSONRenderer()
],
context_class=dict,
logger_factory=structlog.stdlib.LoggerFactory(),
wrapper_class=structlog.stdlib.BoundLogger,
cache_logger_on_first_use=True,
)
#
Health Checks
from fastapi import FastAPI
app = FastAPI()
@app.get("/health")
async def health_check():
return {
"status": "healthy",
"version": "1.2.8",
"uptime": get_uptime(),
"players": len(client.players),
"nodes": len(client.nodes)
}
@app.get("/metrics")
async def metrics():
return {
"cpu_usage": psutil.cpu_percent(),
"memory_usage": psutil.virtual_memory().percent,
"active_connections": len(client.players)
}
#
Scaling Strategies
#
Auto-scaling
# Kubernetes HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: sonora-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: sonora
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
#
Load Balancing
# Application load balancer
from sonora.loadbalancer import LoadBalancer
lb = LoadBalancer()
lb.add_backend("node1:2333")
lb.add_backend("node2:2333")
# Route requests
node = lb.get_backend()
track = await node.load_track(query)
#
Backup & Recovery
#
Automated Backups
#!/bin/bash
# backup.sh
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backups"
# Create backup
sonoractl snapshot save "backup_$DATE"
# Upload to cloud
aws s3 cp "$BACKUP_DIR/backup_$DATE.json" "s3://sonora-backups/"
# Cleanup old backups
find $BACKUP_DIR -name "backup_*.json" -mtime +7 -delete
#
Disaster Recovery
# Recovery plan
apiVersion: v1
kind: ConfigMap
metadata:
name: disaster-recovery
data:
recovery.sh: |
#!/bin/bash
# Stop current deployment
kubectl scale deployment sonora --replicas=0
# Restore from backup
sonoractl snapshot restore latest
# Start new deployment
kubectl scale deployment sonora --replicas=3
#
Security Hardening
#
Container Security
# Use non-root user
RUN useradd --create-home --shell /bin/bash sonora
USER sonora
# Minimize attack surface
RUN apt-get remove -y curl wget && \
apt-get autoremove -y && \
apt-get clean
# Security scanning
FROM aquasec/trivy:latest as scanner
COPY --from=builder /app/dist/*.whl .
RUN trivy filesystem --exit-code 1 --no-progress .
#
Network Security
# Network policies
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: sonora-network-policy
spec:
podSelector:
matchLabels:
app: sonora
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: lavalink
ports:
- protocol: TCP
port: 2333
egress:
- to:
- podSelector:
matchLabels:
app: lavalink
ports:
- protocol: TCP
port: 2333
This deployment guide covers production-ready setups for Sonora.