Prerequisites
Before deploying to production:- Built Docker image following the Docker build process
- Environment variables configured (see Configuration)
- Redis instance available for caching and rate limiting
- Notify API backend accessible
- Load balancer or reverse proxy (recommended)
Deployment Architecture
The production deployment uses:- Gunicorn as the WSGI server
- Eventlet worker class for async operations
- Non-root user (
notify) for security - Multi-stage Docker build for minimal image size
Container Startup
Start the production container with theweb command:
Gunicorn Configuration
Production configuration ingunicorn_config.py:
Worker Configuration
Workers: Set to10 worker processes
- Adjust based on CPU cores:
(2 × cores) + 1 - Each worker handles multiple concurrent connections
- Balance between throughput and memory usage
eventlet for async I/O
- Non-blocking I/O for better concurrency
- Efficient for I/O-bound operations (API calls, Redis)
- Handles 1000 concurrent connections per worker
- Override with
HTTP_SERVE_TIMEOUT_SECONDS - Note: Has limited effect with eventlet worker class
- Set appropriate values for document download operations
- Reduces connection overhead
- Improves performance for HTTP/1.1 clients
Security Best Practices
Non-Root User
The production image runs as thenotify user:
- Limits container breakout impact
- Follows principle of least privilege
- Prevents accidental system modifications
File Permissions
All application files owned bynotify:notify:
root:root to prevent tampering:
Bytecode Compilation
Pre-compile Python bytecode for integrity:- Faster application startup
- Prevents runtime bytecode injection
- Validates Python syntax at build time
Health Checks
Implement container health checks for orchestration platforms:Resource Limits
Set appropriate container resource limits:- Base Python + Flask: ~200-300MB
- Per Gunicorn worker: ~100-150MB
- 10 workers: ~1.5GB recommended minimum
- Add headroom for peak traffic
Logging
Production logging configuration:Log Directory
Created in the production image:Gunicorn Logs
Errors logged to stdout:Python Logging
Unbuffered output for real-time logs:Monitoring
Key Metrics
Monitor these metrics for production health:- Request rate: Total requests per second
- Response time: P50, P95, P99 latencies
- Error rate: 4xx and 5xx responses
- Worker utilization: Active vs idle workers
- Memory usage: Per worker and total
- Redis connections: Active connections and command latency
Prometheus Integration
Thenotifications-utils package provides Prometheus metrics.
Expose metrics endpoint:
Deployment Checklist
Before deploying to production:- Build production Docker image
- Set all required environment variables
- Configure Redis connection
- Set up health check endpoint
- Configure resource limits
- Enable log aggregation
- Set up monitoring and alerts
- Test document download flow
- Verify rate limiting behavior
- Configure reverse proxy/load balancer
- Enable HTTPS/TLS termination
- Review security headers
- Test graceful shutdown
- Document rollback procedure
Scaling
Horizontal Scaling
Run multiple container instances behind a load balancer:- Redis sessions must be centralized
- Use sticky sessions if needed
- Coordinate rate limiting across instances
Vertical Scaling
Adjust worker count based on load:Version Management
The build process generates version information:app/version.py:
- Expose via
/_statusendpoint - Include in error reports
- Track deployed versions
- Correlate with git commits
Rollback Strategy
-
Tag Docker images with git commit SHA:
- Keep previous images available for quick rollback
- Test rollback procedure regularly
-
Monitor deployment with staged rollouts:
Production Environment Variables
Essential variables for production:| Variable | Required | Description |
|---|---|---|
PORT | Yes | HTTP server port (e.g., 7001) |
HTTP_SERVE_TIMEOUT_SECONDS | No | Gunicorn timeout (default: 30) |
NOTIFY_ENVIRONMENT | Yes | Environment name (production) |
REDIS_ENABLED | Yes | Enable Redis (true) |
REDIS_URL | Yes | Redis connection string |
API_HOST_NAME | Yes | Notify API backend URL |
SECRET_KEY | Yes | Flask secret key |
DANGEROUS_SALT | Yes | Token signing salt |
Cloud Foundry Deployment
The application uses/home/vcap paths compatible with Cloud Foundry:
Next Steps
- Review Docker Build for image creation
- Configure Environment Variables