Configure Docker to use Gunicorn instead of Flask development server for production deployment. Updated SocketIO configuration for gevent compatibility.
This commit is contained in:
@@ -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"]
|
@@ -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'],
|
||||
|
@@ -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
5
run.py
@@ -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
16
wsgi.py
Normal 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()
|
Reference in New Issue
Block a user