Configure Docker to use Gunicorn instead of Flask development server for production deployment. Updated SocketIO configuration for gevent compatibility.

This commit is contained in:
2025-08-26 08:36:54 +00:00
parent eedaa253e4
commit 2fe272bd00
5 changed files with 28 additions and 6 deletions

View File

@@ -36,5 +36,5 @@ EXPOSE 5000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD python -c "import requests; requests.get('http://localhost:5000/health', timeout=2)" || exit 1
# Run the application
CMD ["python", "run.py"]
# Run the application with Gunicorn using gevent workers for SocketIO compatibility
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "4", "--worker-class", "gevent", "--worker-connections", "1000", "--timeout", "30", "wsgi:app"]

View File

@@ -12,9 +12,10 @@ from config import config
from app.models import SimulationManager
# Initialize SocketIO with enhanced proxy support
# For Gunicorn compatibility, we need to set the async_mode to 'gevent'
socketio = SocketIO(
cors_allowed_origins="*",
async_mode='threading',
async_mode='gevent' if os.getenv('FLASK_ENV') == 'production' else 'threading',
logger=False, # Disable to avoid log spam in production
engineio_logger=False,
# Transport order: try websocket first, then polling
@@ -54,7 +55,7 @@ def create_app(config_name=None):
# Initialize extensions with proxy-friendly settings
socketio.init_app(
app,
async_mode='threading',
async_mode='gevent' if config_name == 'production' else 'threading',
cors_allowed_origins="*",
allow_upgrades=True,
transports=['websocket', 'polling'],

View File

@@ -2,4 +2,6 @@ Flask>=2.0.0
Flask-SocketIO>=5.0.0
numpy>=1.21.0
matplotlib>=3.5.0
plotly>=5.0.0
plotly>=5.0.0
gunicorn>=20.0.0
gevent>=21.0.0

5
run.py
View File

@@ -15,8 +15,11 @@ if __name__ == '__main__':
debug_mode = config_name == 'development'
port = int(os.getenv('PORT', 5000)) # Use PORT env var or default to 5000
# For production deployment, allow unsafe werkzeug or use a proper WSGI server
# For production deployment with Gunicorn, SocketIO will be handled by Gunicorn
# For development, we use SocketIO's built-in server
if config_name == 'production':
# In production, Gunicorn will handle the server
# This is just a fallback
socketio.run(app, debug=False, host='0.0.0.0', port=port, allow_unsafe_werkzeug=True)
else:
socketio.run(app, debug=debug_mode, host='0.0.0.0', port=port)

16
wsgi.py Normal file
View File

@@ -0,0 +1,16 @@
#!/usr/bin/env python3
"""
WSGI entry point for the Markov Economics Flask application.
This file is used by Gunicorn to serve the application in production.
"""
import os
from app import create_app
# Use FLASK_ENV if set, otherwise default to production for Gunicorn
config_name = os.getenv('FLASK_ENV', 'production')
app = create_app(config_name)
if __name__ == "__main__":
# This is just for testing purposes
app.run()