Deployment Guide¶
Production deployment guide for Certana platform.
Pre-Deployment Checklist¶
- Code reviewed and tested
- Environment variables configured
- Database migrations ready
- SSL certificates obtained
- Rate limiting configured
- Monitoring setup
- Backup strategy in place
- Security audit completed
Deployment Options¶
1. Docker + Docker Compose¶
Build Docker Images¶
# Backend
cd backend
docker build -t certana-backend:latest .
docker tag certana-backend:latest your-registry/certana-backend:1.0.0
# Frontend
cd ../frontend
docker build -t certana-frontend:latest .
# Extension (built separately)
cd ../browser
npm run build
Push to Registry¶
docker login your-registry
docker push your-registry/certana-backend:1.0.0
docker push your-registry/certana-frontend:1.0.0
Deploy with Docker Compose¶
# docker-compose.prod.yml
version: '3.9'
services:
backend:
image: your-registry/certana-backend:1.0.0
environment:
ENVIRONMENT: production
DATABASE_URL: postgresql+asyncpg://certana:${DB_PASSWORD}@db:5432/certana
REDIS_URL: redis://redis:6379/0
ports:
- "8000:8000"
depends_on:
- db
- redis
restart: always
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
frontend:
image: your-registry/certana-frontend:1.0.0
ports:
- "3000:3000"
restart: always
db:
image: postgres:15-alpine
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: certana
POSTGRES_USER: certana
volumes:
- pg_data:/var/lib/postgresql/data
restart: always
redis:
image: redis:7-alpine
restart: always
volumes:
pg_data:
Deploy¶
docker-compose -f docker-compose.prod.yml up -d
2. Kubernetes Deployment¶
Prerequisites¶
- Kubernetes cluster (AWS EKS, GCP GKE, etc.)
- kubectl configured
- Helm (optional but recommended)
Create Namespace¶
kubectl create namespace certana-prod
kubectl config set-context --current --namespace=certana-prod
Create ConfigMap & Secrets¶
# ConfigMap for non-sensitive config
kubectl create configmap certana-config \
--from-literal=ENVIRONMENT=production \
--from-literal=LOG_LEVEL=info
# Secret for sensitive data
kubectl create secret generic certana-secrets \
--from-literal=DATABASE_URL=postgresql+asyncpg://... \
--from-literal=REDIS_URL=redis://... \
--from-literal=SECRET_KEY=...
Backend Deployment¶
# k8s/backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: certana-backend
namespace: certana-prod
spec:
replicas: 3
selector:
matchLabels:
app: certana-backend
template:
metadata:
labels:
app: certana-backend
spec:
containers:
- name: backend
image: your-registry/certana-backend:1.0.0
ports:
- containerPort: 8000
env:
- name: ENVIRONMENT
valueFrom:
configMapKeyRef:
name: certana-config
key: ENVIRONMENT
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: certana-secrets
key: DATABASE_URL
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 10
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: certana-backend
namespace: certana-prod
spec:
type: LoadBalancer
ports:
- port: 8000
targetPort: 8000
selector:
app: certana-backend
Deploy to Kubernetes¶
# Create namespace
kubectl create namespace certana-prod
# Deploy backend
kubectl apply -f k8s/backend-deployment.yaml
# Check status
kubectl get pods -n certana-prod
kubectl logs -f deployment/certana-backend -n certana-prod
3. Serverless Deployment (AWS Lambda)¶
Package Backend for Lambda¶
# Install serverless framework
npm install -g serverless
# Create serverless config
cat > serverless.yml << EOF
service: certana-backend
provider:
name: aws
runtime: python3.11
region: us-east-1
environment:
ENVIRONMENT: production
DATABASE_URL: ${ssm:/certana/db_url}
functions:
api:
handler: src/main.handler
events:
- http:
path: /{proxy+}
method: ANY
cors: true
plugins:
- serverless-python-requirements
- serverless-wsgi
EOF
# Deploy
serverless deploy
SSL/TLS Certificate¶
Using Let's Encrypt with Certbot¶
# Install certbot
sudo apt-get install certbot python3-certbot-nginx
# Get certificate
sudo certbot certonly --standalone -d yourdomain.com
# Renew automatically
sudo certbot renew --dry-run
Use in Docker¶
FROM nginx:alpine
COPY --from=certbot /etc/letsencrypt /etc/letsencrypt
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]
Environment Configuration¶
Production .env¶
# Application
VERSION=1.0.0
ENVIRONMENT=production
SECRET_KEY=<generate-strong-secret>
MASTER_KEY=<load-from-kms>
# Database
DATABASE_URL=postgresql+asyncpg://certana:${DB_PASSWORD}@db.example.com:5432/certana
DATABASE_POOL_SIZE=30
DATABASE_MAX_OVERFLOW=20
# Redis
REDIS_URL=redis://redis.example.com:6379/0
# CORS
CORS_ORIGINS=https://yourdomain.com,https://app.yourdomain.com
# OAuth
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
# Storage
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
S3_BUCKET_NAME=certana-prod
CDN_BASE_URL=https://cdn.yourdomain.com
# Solana
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
SOLANA_PROGRAM_ID=...
# Rate Limiting
RATE_LIMIT_ENABLED=true
RATE_LIMIT_PER_MINUTE=60
Database Setup¶
Production PostgreSQL¶
# Connect to production database
psql -h db.example.com -U certana -d certana
# Run migrations
alembic upgrade head
# Verify
\dt # List tables
\di # List indexes
Backup Strategy¶
# Daily backup script (cron)
#!/bin/bash
BACKUP_DIR="/backups/database"
DATE=$(date +%Y%m%d_%H%M%S)
pg_dump -h db.example.com -U certana certana | \
gzip > $BACKUP_DIR/certana_$DATE.sql.gz
# Upload to S3
aws s3 cp $BACKUP_DIR/certana_$DATE.sql.gz \
s3://certana-backups/
# Cleanup old backups (keep 30 days)
find $BACKUP_DIR -mtime +30 -delete
Monitoring & Logging¶
Backend Monitoring¶
# Use CloudWatch (AWS) or similar
import logging
import watchtower
logger = logging.getLogger(__name__)
logger.addHandler(watchtower.CloudWatchLogHandler())
Key Metrics¶
- Request latency (p50, p95, p99)
- Error rate
- Throughput (requests/sec)
- Database connection pool usage
- Memory usage
- CPU usage
Set up Alarms¶
# AWS CloudWatch Alarm
import boto3
cloudwatch = boto3.client('cloudwatch')
cloudwatch.put_metric_alarm(
AlarmName='CertanaBackendErrors',
MetricName='ErrorRate',
Namespace='Certana',
Statistic='Average',
Period=300,
EvaluationPeriods=1,
Threshold=5.0, # 5% error rate
ComparisonOperator='GreaterThanThreshold',
)
CI/CD Pipeline¶
GitHub Actions Example¶
name: Deploy to Production
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install -r backend/requirements.txt
- name: Run tests
run: |
pytest backend/tests/
- name: Build Docker image
run: |
docker build -t certana-backend:latest backend/
- name: Push to registry
run: |
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
docker push certana-backend:latest
- name: Deploy to Kubernetes
run: |
kubectl set image deployment/certana-backend \
backend=certana-backend:latest \
--namespace=certana-prod
Health Checks¶
Backend Health Endpoint¶
@app.get("/health")
async def health_check():
return {
"status": "healthy",
"version": settings.VERSION,
"timestamp": datetime.utcnow().isoformat(),
"checks": {
"database": await check_database(),
"redis": check_redis(),
"ml_models": check_ml_models(),
}
}
Rollback Strategy¶
# Kubernetes rollback
kubectl rollout history deployment/certana-backend
kubectl rollout undo deployment/certana-backend --to-revision=2
# Docker rollback
docker service update --image old-image:tag certana_backend
Post-Deployment Verification¶
# Test API
curl -X GET https://api.yourdomain.com/v1/health
# Test database
psql -h db.example.com -U certana -d certana -c "SELECT COUNT(*) FROM users;"
# Test storage
aws s3 ls s3://certana-prod/
# Test Solana connection
curl https://api.mainnet-beta.solana.com -X POST \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"getHealth"}'
# Test frontend
open https://yourdomain.com
Scaling¶
Horizontal Scaling¶
# Kubernetes HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: certana-backend-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: certana-backend
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Disaster Recovery¶
RTO/RPO Targets¶
- RTO (Recovery Time Objective): 15 minutes
- RPO (Recovery Point Objective): 1 hour
Backup & Restore¶
# Test restore from backup
pg_restore -h new-db.example.com -U certana -d certana_restore \
/backups/database/certana_20240115_100000.sql.gz
# Verify restored data
psql -h new-db.example.com -U certana -d certana_restore \
-c "SELECT COUNT(*) FROM assets;"