Skip to content

Commit 73b2fb6

Browse files
committed
analysis on using subprocess instead of gunicorn and removing references to virtual path in env files
1 parent a73e642 commit 73b2fb6

3 files changed

Lines changed: 49 additions & 16 deletions

File tree

.env.example

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,6 @@ NGINX_PORT=
3636
# - acme-companion: Requests SSL certificate for this domain from Let's Encrypt
3737
HOST=
3838

39-
# Path on the domain where the dashboard is accessible
40-
# If set, the dashboard will ONLY be accessible at this specific path
41-
# Examples:
42-
# - VIRTUAL_PATH=/survey-dashboard → https://your-domain.com/survey-dashboard
43-
# - VIRTUAL_PATH=/dashboard → https://your-domain.com/dashboard
44-
# - Leave empty for root path → https://your-domain.com/
45-
# IMPORTANT: Must start with / (forward slash)
46-
# All other paths on this domain will return 404
47-
VIRTUAL_PATH=
48-
4939
# ============================================================================
5040
# SSL/HTTPS Configuration (Let's Encrypt)
5141
# ============================================================================

.env.local.example

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,6 @@ NGINX_PORT=80
3333
# You can only test HTTP locally
3434
HOST=localhost
3535

36-
# Path on the domain where the dashboard is accessible
37-
# Test the same path you'll use in production
38-
# Example: VIRTUAL_PATH=/2021community
39-
# Leave empty to serve from root: http://localhost/
40-
VIRTUAL_PATH=/2021community
41-
4236
# ============================================================================
4337
# SSL/HTTPS Configuration (Let's Encrypt)
4438
# ============================================================================

survey_dashboard/scripts.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,44 @@
1111
###############################################################################
1212
"""
1313
Command 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

1654
import 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

Comments
 (0)