1111###############################################################################
1212"""
1313Command line scripts for the survey dashboard.
14+
15+ DEPLOYMENT ARCHITECTURE:
16+ ========================
17+ This application uses Panel's built-in server (via `panel serve`) rather than
18+ traditional WSGI servers like Gunicorn. This is the CORRECT and RECOMMENDED
19+ approach for Panel applications.
20+
21+ Why subprocess + `panel serve` instead of Gunicorn:
22+ ----------------------------------------------------
23+ 1. **WebSocket Support**: Panel apps require WebSocket connections for real-time
24+ interactivity. Panel is built on Bokeh Server which uses Tornado's WebSocket
25+ implementation. Standard WSGI servers like Gunicorn don't natively support
26+ WebSockets in the same way.
27+
28+ 2. **State Management**: Panel/Bokeh Server manages application state and sessions
29+ in a specific way that requires Tornado's event loop. Gunicorn's worker model
30+ doesn't provide this.
31+
32+ 3. **Bokeh Protocol**: The Bokeh Server protocol handles bidirectional communication
33+ between Python and JavaScript using a custom protocol over WebSockets. This is
34+ deeply integrated with Tornado.
35+
36+ 4. **Official Recommendation**: The Panel documentation recommends using `panel serve`
37+ for production deployments. See: https://panel.holoviz.org/how_to/deployment/
38+
39+ 5. **Built-in Production Features**: `panel serve` includes production-ready features:
40+ - Multi-process scaling via --num-procs
41+ - WebSocket origin validation via --allow-websocket-origin
42+ - Static file serving
43+ - Load balancing across worker processes
44+
45+ Alternative Approaches (Not Recommended):
46+ -----------------------------------------
47+ - **Gunicorn + Flask wrapper**: Possible but adds unnecessary complexity and
48+ requires careful configuration of worker types (gevent/eventlet)
49+ - **Embedding Panel in ASGI**: Possible with Daphne/Uvicorn but adds overhead
50+
51+ For more details, see DEPLOYMENT.md in the project root.
1452"""
1553
1654import argparse
@@ -23,6 +61,17 @@ def run_app():
2361 """Run the survey dashboard application using Panel serve.
2462
2563 Supports both development and production modes via command-line arguments.
64+
65+ Kubernetes Deployment Note:
66+ ---------------------------
67+ For Kubernetes deployments, each pod should run a single process (no --num-procs).
68+ Kubernetes handles scaling via pod replicas and load balancing via Services.
69+
70+ Example production deployment:
71+ survey-dashboard --production --host 0.0.0.0 --port 5006
72+
73+ Then scale in Kubernetes:
74+ kubectl scale deployment survey-dashboard --replicas=3
2675 """
2776 # Parse command-line arguments
2877 parser = argparse .ArgumentParser (description = "Run the HMC Survey Dashboard" )
0 commit comments