Configuration Guide
Comprehensive configuration guide for the FeelyFeely CDN service, covering all environment variables, service integrations, and deployment settings.
Environment Configuration
Core Configuration Files
| File | Purpose | Description |
|---|---|---|
.env | Environment variables | Main configuration file |
gunicorn_config.py | Server configuration | Production server settings |
server.ini | uWSGI configuration | Alternative server setup |
db_config.py | Database setup | Database connection configuration |
Database Configuration
MySQL Configuration
Primary Database (Main)
# Main application database
MYSQL_HOST=your-mysql-host.com
MYSQL_USER=orc8r
MYSQL_PASSWORD=your-secure-password
MYSQL_DB=main
MYSQL_CURSORCLASS=DictCursor
MYSQL_PORT=25060
# SQLAlchemy connection string
MYSQL_MAIN_BRIDGE=mysql+pymysql://orc8r:password@host:25060/main
Business Database
# Business-specific database
MYSQL_BIZ_HOST=your-mysql-host.com
MYSQL_BIZ_USER=bzns
MYSQL_BIZ_PASSWORD=your-business-password
MYSQL_BIZ_DB=business
MYSQL_BIZ_CURSORCLASS=DictCursor
MYSQL_BIZ_PORT=25060
# SQLAlchemy connection string
MYSQL_BIZ_BRIDGE=mysql+pymysql://bzns:password@host:25060/business
MySQL Connection Options
| Parameter | Description | Default | Options |
|---|---|---|---|
MYSQL_CURSORCLASS | Cursor type for results | DictCursor | DictCursor, Cursor |
MYSQL_PORT | Database port | 3306 | Any valid port |
| Connection pooling | Automatic | Enabled | Via Flask-MySQLdb |
MongoDB Configuration
Production MongoDB
# Production MongoDB with SSL
MONGODB_MAIN_PROD=mongodb+srv://username:[email protected]/gateway?authSource=admin&replicaSet=db-mongodb-1&tls=true&tlsCAFile=/workspace/mongodb-1-cert.crt
Development MongoDB
# Development MongoDB (SSL cert path relative)
MONGODB_MAIN_DEV_PREFIX=mongodb+srv://username:[email protected]/gateway?authSource=admin&replicaSet=db-mongodb-1&tls=true&tlsCAFile=
MongoDB Features Configuration
| Feature | Configuration | Description |
|---|---|---|
| SSL/TLS | tls=true&tlsCAFile=cert.crt | Encrypted connections |
| Replica Set | replicaSet=db-mongodb-1 | High availability |
| Authentication | authSource=admin | Database authentication |
| Connection Pooling | Automatic | Via PyMongo |
Storage Configuration
DigitalOcean Spaces
User Assets Storage
DO_USER_ASSET_SPACES_REGION=fra1
DO_USER_ASSET_SPACES_KEY=DO00ULE7P34ENYA9A9WL
DO_USER_ASSET_SPACES_SECRET=your-secret-key
DO_USER_ASSET_SPACES_BUCKET_NAME=ff.user.assets
Organization Assets Storage
DO_ORG_ASSET_SPACES_REGION=fra1
DO_ORG_ASSET_SPACES_KEY=DO00NWQW6VKH39PLCH94
DO_ORG_ASSET_SPACES_SECRET=your-org-secret-key
DO_ORG_ASSET_SPACES_BUCKET_NAME=ff.organization.assets
Mobile Device Photo Storage
DO_MOBILE_DEVICE_PHOTO_SPACES_REGION=fra1
DO_MOBILE_DEVICE_PHOTO_SPACES_KEY=DO00TGDUUK8JZZ3ANZEN
DO_MOBILE_DEVICE_PHOTO_SPACES_SECRET=your-mobile-secret-key
DO_MOBILE_DEVICE_PHOTO_SPACES_BUCKET_NAME=ff.mobiledevice.photos
Vehicle Photo Storage
DO_VEHICLE_PHOTO_SPACES_REGION=fra1
DO_VEHICLE_PHOTO_SPACES_KEY=DO00KDLXHKRNWEHLPXWZ
DO_VEHICLE_PHOTO_SPACES_SECRET=your-vehicle-secret-key
DO_VEHICLE_PHOTO_SPACES_BUCKET_NAME=ff.vehicle.photos
Available Regions
| Region Code | Location | Description |
|---|---|---|
nyc1 | New York 1 | US East Coast |
nyc3 | New York 3 | US East Coast |
sfo3 | San Francisco 3 | US West Coast |
fra1 | Frankfurt 1 | Europe |
ams3 | Amsterdam 3 | Europe |
sgp1 | Singapore 1 | Asia Pacific |
blr1 | Bangalore 1 | Asia Pacific |
Authentication Configuration
Keycloak Integration
# Keycloak server configuration
KC_URL=https://auth.clappnet.com:8443/
KC_REALM=feelyfeely
KC_CLIENT_ID=web
KC_SECRET=YZLj3sp9USxCoGni7fi7uwiK6LOR7p9C
[email protected]
KC_ADMIN_PASS=your-admin-password
Keycloak Settings
| Parameter | Description | Example |
|---|---|---|
KC_URL | Keycloak server URL | https://auth.example.com/ |
KC_REALM | Authentication realm | feelyfeely |
KC_CLIENT_ID | OAuth client ID | web |
KC_SECRET | Client secret | secret-key |
Image Processing Configuration
Uploadcare Integration
# Uploadcare API credentials
UPLOAD_CARE_PUBLIC_KEY=d0277e43145fbb62bcfe
UPLOAD_CARE_SECRET_KEY=d7c992f55b5982665074
Uploadcare Features
| Feature | Configuration | Description |
|---|---|---|
| File Upload | Automatic | Direct file uploads |
| Image Processing | URL-based | Real-time transformations |
| CDN Delivery | Global | Worldwide content delivery |
| Format Optimization | Automatic | WebP, JPEG, PNG optimization |
Image Operation Presets
Configure in view/api/image.py:
scale_crop_size_ops = [
{"name": "thumbnail", "width": 150, "height": 150, "operation": "scale_crop/150x150/smart"},
{"name": "small", "width": 320, "height": 240, "operation": "scale_crop/320x240/smart"},
{"name": "medium", "width": 640, "height": 480, "operation": "scale_crop/640x480/smart"},
{"name": "large", "width": 1024, "height": 768, "operation": "scale_crop/1024x768/smart"},
{"name": "hero", "width": 1920, "height": 1080, "operation": "scale_crop/1920x1080/smart"}
]
Quality Settings
quality_ops = {
"auto": "quality/auto",
"normal": "quality/normal",
"better": "quality/better",
"best": "quality/best",
"lighter": "quality/lighter",
"lightest": "quality/lightest"
}
Server Configuration
Gunicorn Configuration (gunicorn_config.py)
from multiprocessing import cpu_count
# Server binding
bind = '0.0.0.0:8080'
# Worker configuration
workers = (2 * cpu_count()) + 1
worker_class = 'gevent'
worker_connections = 1000
# Timeout settings
timeout = 60
keepalive = 2
# Process naming
proc_name = 'ff-cdn'
# Logging
accesslog = '-'
errorlog = '-'
loglevel = 'info'
# Worker recycling
max_requests = 1000
max_requests_jitter = 50
Worker Configuration Options
| Parameter | Description | Recommended |
|---|---|---|
workers | Number of worker processes | (2 * CPU cores) + 1 |
worker_class | Worker type | gevent for async I/O |
worker_connections | Max connections per worker | 1000 |
timeout | Worker timeout | 60 seconds |
uWSGI Configuration (server.ini)
[uwsgi]
module = wsgi:app
master = true
processes = 10
socket = con8r.sock
chmod-socket = 660
vacuum = true
die-on-term = true
# Performance settings
enable-threads = true
thread-stack-size = 512
lazy-apps = true
# Buffer settings
buffer-size = 32768
post-buffering = 8192
# Logging
log-date = true
log-prefix = [FF-CDN]
Development Configuration
Development Server Settings
In server.py:
if __name__ == "__main__":
# Development configuration
app.run(
host="0.0.0.0",
port=5065,
debug=True,
threaded=True
)
Debug Configuration
# Enable debug mode
FLASK_ENV=development
FLASK_DEBUG=1
# Disable SSL verification (development only)
VERIFY_SSL=False
Production Configuration
Environment-Specific Settings
Production Environment
# Application environment
ENVIRONMENT=production
FLASK_ENV=production
DEBUG=False
# Security settings
SSL_VERIFY=True
SECURE_HEADERS=True
# Logging
LOG_LEVEL=INFO
LOG_FORMAT=structured
Staging Environment
# Application environment
ENVIRONMENT=staging
FLASK_ENV=staging
DEBUG=True
# Reduced security for testing
SSL_VERIFY=False
Security Configuration
SSL/TLS Settings
# Force HTTPS redirects
FORCE_HTTPS=True
# HSTS settings
HSTS_MAX_AGE=31536000
HSTS_INCLUDE_SUBDOMAINS=True
# Content Security Policy
CSP_DEFAULT_SRC="'self'"
CSP_IMG_SRC="'self' data: https:"
Monitoring Configuration
Logging Configuration
import logging
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('logs/app.log'),
logging.StreamHandler()
]
)
Health Check Configuration
@app.route('/health')
def health_check():
"""Health check endpoint for monitoring"""
return {
"status": "healthy",
"version": "1.0.0",
"timestamp": datetime.utcnow().isoformat(),
"services": {
"mysql": check_mysql_health(),
"mongodb": check_mongodb_health(),
"spaces": check_spaces_health(),
"uploadcare": check_uploadcare_health()
}
}
Performance Tuning
Database Optimization
MySQL Connection Pool
# Connection pool settings
app.config['MYSQL_DATABASE_POOL_NAME'] = 'ff_pool'
app.config['MYSQL_DATABASE_POOL_SIZE'] = 10
app.config['MYSQL_DATABASE_POOL_RESET_SESSION'] = True
MongoDB Connection Pool
# MongoDB connection options
client = MongoClient(
connection_string,
maxPoolSize=50,
minPoolSize=10,
maxIdleTimeMS=30000,
waitQueueTimeoutMS=5000
)
Caching Configuration
Application-Level Caching
from flask_caching import Cache
cache = Cache(app, config={
'CACHE_TYPE': 'redis',
'CACHE_REDIS_HOST': 'localhost',
'CACHE_REDIS_PORT': 6379,
'CACHE_REDIS_DB': 0,
'CACHE_DEFAULT_TIMEOUT': 3600
})
Error Handling Configuration
Error Response Settings
# Custom error handlers
@app.errorhandler(404)
def not_found(error):
return jsonify({
'status': 404,
'error': 'Resource not found'
}), 404
@app.errorhandler(500)
def internal_error(error):
return jsonify({
'status': 500,
'error': 'Internal server error'
}), 500
Retry Configuration
# Retry settings for external services
RETRY_ATTEMPTS = 3
RETRY_BACKOFF = 1.5
RETRY_TIMEOUT = 30
Environment Validation
Configuration Validation Script
import os
from decouple import config
def validate_configuration():
"""Validate all required configuration variables"""
required_vars = [
'MYSQL_HOST', 'MYSQL_USER', 'MYSQL_PASSWORD',
'MONGODB_MAIN_PROD',
'DO_USER_ASSET_SPACES_KEY', 'DO_USER_ASSET_SPACES_SECRET',
'UPLOAD_CARE_PUBLIC_KEY', 'UPLOAD_CARE_SECRET_KEY',
'KC_URL', 'KC_REALM', 'KC_CLIENT_ID'
]
missing_vars = []
for var in required_vars:
try:
config(var)
except:
missing_vars.append(var)
if missing_vars:
raise EnvironmentError(f"Missing required environment variables: {missing_vars}")
print("✓ All required configuration variables are set")
if __name__ == "__main__":
validate_configuration()
Configuration Best Practices
Security Best Practices
- Environment Separation: Use different credentials for each environment
- Secret Rotation: Regularly rotate API keys and passwords
- Minimal Permissions: Grant only necessary permissions
- Environment Variables: Never commit secrets to version control
Performance Best Practices
- Connection Pooling: Configure appropriate pool sizes
- Timeout Settings: Set reasonable timeouts for external services
- Caching: Enable caching for frequently accessed data
- Worker Configuration: Match worker count to available resources
Operational Best Practices
- Health Checks: Implement comprehensive health monitoring
- Logging: Configure structured logging for easier debugging
- Monitoring: Set up alerts for critical configuration changes
- Documentation: Keep configuration documentation up to date
Troubleshooting Configuration Issues
Common Configuration Problems
Database Connection Issues
# Test MySQL connection
python -c "from db_config import mysql; print('MySQL connected:', mysql.connection.open)"
# Test MongoDB connection
python -c "from dbutils.mongodb import MongoDB; MongoDB()"
Storage Connection Issues
# Test DigitalOcean Spaces
python -c "
from models.digitalocean.spaces import DigitalOceanSpaces
spaces = DigitalOceanSpaces('fra1', 'https://fra1.digitaloceanspaces.com', 'key', 'secret')
print('Spaces connected')
"
Authentication Issues
# Verify Keycloak configuration
curl "${KC_URL}realms/${KC_REALM}/.well-known/openid_configuration"
Configuration Validation Commands
# Validate environment file
python -c "from decouple import config; print('Environment loaded successfully')"
# Check required dependencies
pip check
# Validate database schemas
python -c "from db_config import mysql; cursor = mysql.connection.cursor(); cursor.execute('SHOW TABLES')"