This guide provides comprehensive instructions for deploying the Bookstore API to production environments.
# Copy production environment file
cp .env.production.example .env.production
# Edit and configure all values
nano .env.production
Important: Update these values:
SECRET_KEY: Generate with openssl rand -hex 32SQLALCHEMY_DATABASE_URL: PostgreSQL connection stringBACKEND_CORS_ORIGINS: Your domain(s)# Build production image
docker-compose -f docker-compose.prod.yml build
# Start services
docker-compose -f docker-compose.prod.yml up -d
# Run database migrations
docker-compose -f docker-compose.prod.yml exec api alembic upgrade head
# Seed database (optional)
docker-compose -f docker-compose.prod.yml exec api python scripts/seed_database.py
# Check service status
docker-compose -f docker-compose.prod.yml ps
# Check logs
docker-compose -f docker-compose.prod.yml logs -f api
# Test API
curl http://localhost:8000/health
curl http://localhost:8000/api/v1/health/ready
kubectl create namespace bookstore
kubectl config set-context --current --namespace=bookstore
# Create secrets from file
kubectl create secret generic bookstore-secrets \
--from-literal=secret-key=$(openssl rand -hex 32) \
--from-literal=database-url='postgresql://user:pass@host:5432/db'
# Or apply from secrets.yaml
cp k8s/secrets.yaml.example k8s/secrets.yaml
# Edit secrets.yaml with your values
kubectl apply -f k8s/secrets.yaml
# Apply all manifests
kubectl apply -f k8s/
# Or apply individually
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/hpa.yaml
kubectl apply -f k8s/ingress.yaml
# Check pods
kubectl get pods
kubectl describe pod <pod-name>
# Check services
kubectl get svc
# Check ingress
kubectl get ingress
# View logs
kubectl logs -f deployment/bookstore-api
# Test health check
kubectl port-forward svc/bookstore-api-service 8000:80
curl http://localhost:8000/api/v1/health/ready
# Create database and user
psql -U postgres
CREATE DATABASE bookstore;
CREATE USER bookstore WITH ENCRYPTED PASSWORD 'your-secure-password';
GRANT ALL PRIVILEGES ON DATABASE bookstore TO bookstore;
\q
# Run migrations
alembic upgrade head
# Or in Docker
docker-compose -f docker-compose.prod.yml exec api alembic upgrade head
# Create new migration
alembic revision --autogenerate -m "Description of changes"
# Apply migrations
alembic upgrade head
# Rollback one version
alembic downgrade -1
# View migration history
alembic history
Metrics are exposed at /metrics endpoint:
# Access metrics
curl http://localhost:8000/metrics
Available metrics:
http_requests_total: Total HTTP requestshttp_request_duration_seconds: Request durationhttp_requests_in_progress: In-progress requestsdatabase_connections: Active DB connections/health: Basic health check/api/v1/health/live: Liveness probe/api/v1/health/ready: Readiness probe/api/v1/health/detailed: Detailed health informationLogs are structured and output to stdout. Configure your log aggregation:
# Example: Fluentd, Logstash, etc.
# All requests include X-Request-ID for tracing
# Setup cron job for daily backups
0 2 * * * /path/to/scripts/backup_database.sh
# Or use K8s CronJob
kubectl apply -f k8s/cronjob-backup.yaml
# Run backup script
export DB_HOST=localhost
export DB_PORT=5432
export DB_NAME=bookstore
export DB_USER=bookstore
export DB_PASSWORD=your-password
./scripts/backup_database.sh
# Restore database
./scripts/restore_database.sh /backups/bookstore_20240101_120000.sql.gz
.env files or secrets to version control# Generate SSL certificate (Let's Encrypt)
certbot certonly --standalone -d api.yourdomain.com
# Or use cert-manager in Kubernetes
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml
All security headers are automatically added:
Configured at multiple levels:
# config.py
WEB_CONCURRENCY = 4 # Number of worker processes
MAX_WORKERS = 10 # Max concurrent workers
# Increase pool size for high traffic
engine = create_engine(
DATABASE_URL,
pool_size=20,
max_overflow=40,
pool_pre_ping=True
)
# Add caching for frequently accessed data
from redis import Redis
redis_client = Redis.from_url(REDIS_URL)
worker_processes auto;
worker_connections 2048;
keepalive_timeout 65;
# Check logs
docker-compose logs api
kubectl logs deployment/bookstore-api
# Check environment variables
docker-compose exec api env
kubectl exec deployment/bookstore-api -- env
# Test database connectivity
docker-compose exec api python -c "
from app.db.database import engine
try:
engine.connect()
print('Connected!')
except Exception as e:
print(f'Error: {e}')
"
# Check memory usage
docker stats
kubectl top pods
# Increase memory limits
# Edit k8s/deployment.yaml resources section
# Check CPU usage
docker stats
kubectl top pods
# Scale horizontally
kubectl scale deployment/bookstore-api --replicas=5
# Enable debug logging
export LOG_LEVEL=DEBUG
# Access container shell
docker-compose exec api /bin/bash
kubectl exec -it deployment/bookstore-api -- /bin/bash
# Check network connectivity
kubectl run -it --rm debug --image=curlimages/curl --restart=Never -- sh
Before going to production:
For issues and questions: