RayMelius Claude Sonnet 4.6 commited on
Commit
e1128ec
Β·
1 Parent(s): 53c4fc5

Add Frontend button to dashboard; wire frontend into single-container

Browse files

Dashboard:
- FRONTEND_URL env var injected into template; button only shown when set
- docker-compose: FRONTEND_URL=http://localhost:5000 added to dashboard service
- Button opens frontend in new tab (indigo pill style, matching FIX UI)

Single-container (HuggingFace):
- nginx: /frontend/ route added β†’ localhost:5003
- entrypoint.sh: starts frontend on port 5003 with correct template folder
- Dockerfile: copies frontend.py + templates to /app/frontend_templates/
- frontend.py: TEMPLATE_FOLDER env var support added
- Dockerfile: also copies market_schedule.txt to /app/data/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Dockerfile CHANGED
@@ -40,6 +40,7 @@ WORKDIR /app
40
 
41
  COPY shared/ /app/shared/
42
  COPY shared_data/securities.txt /app/data/securities.txt
 
43
 
44
  # Matcher service
45
  COPY matcher/matcher.py /app/matcher.py
@@ -52,6 +53,10 @@ COPY md_feeder/mdf_simulator.py /app/mdf_simulator.py
52
  COPY dashboard/dashboard.py /app/dashboard.py
53
  COPY dashboard/templates/ /app/templates/
54
 
 
 
 
 
55
  # FIX OEG (Order Entry Gateway)
56
  COPY fix_oeg/fix_oeg_server.py /app/fix_oeg/fix_oeg_server.py
57
  COPY fix_oeg/FIX44.xml /app/fix_oeg/FIX44.xml
 
40
 
41
  COPY shared/ /app/shared/
42
  COPY shared_data/securities.txt /app/data/securities.txt
43
+ COPY shared_data/market_schedule.txt /app/data/market_schedule.txt
44
 
45
  # Matcher service
46
  COPY matcher/matcher.py /app/matcher.py
 
53
  COPY dashboard/dashboard.py /app/dashboard.py
54
  COPY dashboard/templates/ /app/templates/
55
 
56
+ # Frontend (order entry) service
57
+ COPY frontend/frontend.py /app/frontend.py
58
+ COPY frontend/templates/ /app/frontend_templates/
59
+
60
  # FIX OEG (Order Entry Gateway)
61
  COPY fix_oeg/fix_oeg_server.py /app/fix_oeg/fix_oeg_server.py
62
  COPY fix_oeg/FIX44.xml /app/fix_oeg/FIX44.xml
dashboard/dashboard.py CHANGED
@@ -22,7 +22,8 @@ sse_clients_lock = threading.Lock()
22
  # Session state
23
  session_state = {"active": False, "start_time": None, "suspended": False, "mode": "automatic"}
24
 
25
- SCHEDULE_FILE = os.getenv("SCHEDULE_FILE", "/app/shared_data/market_schedule.txt")
 
26
 
27
  # ── OHLCV History ──────────────────────────────────────────────────────────────
28
  HISTORY_DB = os.getenv("HISTORY_DB", "/app/data/dashboard_history.db")
@@ -177,7 +178,7 @@ threading.Thread(target=consume_kafka, daemon=True).start()
177
 
178
  @app.route("/")
179
  def index():
180
- return render_template("index.html")
181
 
182
 
183
  @app.route("/health")
 
22
  # Session state
23
  session_state = {"active": False, "start_time": None, "suspended": False, "mode": "automatic"}
24
 
25
+ SCHEDULE_FILE = os.getenv("SCHEDULE_FILE", "/app/shared_data/market_schedule.txt")
26
+ FRONTEND_URL = os.getenv("FRONTEND_URL", "")
27
 
28
  # ── OHLCV History ──────────────────────────────────────────────────────────────
29
  HISTORY_DB = os.getenv("HISTORY_DB", "/app/data/dashboard_history.db")
 
178
 
179
  @app.route("/")
180
  def index():
181
+ return render_template("index.html", frontend_url=FRONTEND_URL)
182
 
183
 
184
  @app.route("/health")
dashboard/templates/index.html CHANGED
@@ -204,7 +204,8 @@
204
  <button id="day-btn" onclick="toggleDay()" class="btn-day btn-start" disabled>Start of Day</button>
205
  <button id="suspend-btn" onclick="toggleSuspend()" class="btn-day btn-suspend" disabled>Suspend</button>
206
  <button id="mode-btn" onclick="toggleMode()" class="btn-day btn-automatic">Automatic</button>
207
- <a href="/fix/" style="margin-left:auto; padding:4px 14px; background:#6c757d; color:#fff; border-radius:20px; font-size:12px; font-weight:bold; text-decoration:none;">FIX UI</a>
 
208
  </h1>
209
  <div class="container">
210
 
 
204
  <button id="day-btn" onclick="toggleDay()" class="btn-day btn-start" disabled>Start of Day</button>
205
  <button id="suspend-btn" onclick="toggleSuspend()" class="btn-day btn-suspend" disabled>Suspend</button>
206
  <button id="mode-btn" onclick="toggleMode()" class="btn-day btn-automatic">Automatic</button>
207
+ {% if frontend_url %}<a href="{{ frontend_url }}" target="_blank" style="margin-left:auto; padding:4px 14px; background:#5c6bc0; color:#fff; border-radius:20px; font-size:12px; font-weight:bold; text-decoration:none;">Frontend</a>{% endif %}
208
+ <a href="/fix/" style="{% if not frontend_url %}margin-left:auto; {% endif %}padding:4px 14px; background:#6c757d; color:#fff; border-radius:20px; font-size:12px; font-weight:bold; text-decoration:none;">FIX UI</a>
209
  </h1>
210
  <div class="container">
211
 
docker-compose.yml CHANGED
@@ -161,6 +161,7 @@ services:
161
  - matcher
162
  environment:
163
  - MATCHER_URL=http://matcher:6000
 
164
 
165
  volumes:
166
  matcher_data: # Persists SQLite database across container restarts
 
161
  - matcher
162
  environment:
163
  - MATCHER_URL=http://matcher:6000
164
+ - FRONTEND_URL=http://localhost:5000
165
 
166
  volumes:
167
  matcher_data: # Persists SQLite database across container restarts
entrypoint.sh CHANGED
@@ -9,6 +9,8 @@ export MATCHER_URL=http://localhost:6000
9
  export PORT=5000
10
  export FIX_CONFIG=/app/fix_ui/client_hf.cfg
11
  export UI_PORT=5002
 
 
12
 
13
  # ── Kafka (KRaft) ─────────────────────────────────────────────────────────────
14
  echo "[startup] Formatting Kafka storage (KRaft)..."
@@ -63,7 +65,11 @@ echo "[startup] Starting FIX UI Client on port 5002..."
63
  python3 /app/fix_ui/fix_ui_client.py &
64
  sleep 2
65
 
66
- # ── nginx (reverse proxy: port 7860 β†’ dashboard:5000 + fix-ui:5002) ───────────
 
 
 
 
67
  echo "[startup] Starting nginx on port 7860..."
68
  nginx
69
 
 
9
  export PORT=5000
10
  export FIX_CONFIG=/app/fix_ui/client_hf.cfg
11
  export UI_PORT=5002
12
+ export FRONTEND_PORT=5003
13
+ export FRONTEND_URL=/frontend/
14
 
15
  # ── Kafka (KRaft) ─────────────────────────────────────────────────────────────
16
  echo "[startup] Formatting Kafka storage (KRaft)..."
 
65
  python3 /app/fix_ui/fix_ui_client.py &
66
  sleep 2
67
 
68
+ echo "[startup] Starting Frontend on port 5003..."
69
+ PORT=$FRONTEND_PORT TEMPLATE_FOLDER=/app/frontend_templates python3 /app/frontend.py &
70
+ sleep 2
71
+
72
+ # ── nginx (reverse proxy: port 7860 β†’ dashboard:5000 + fix-ui:5002 + frontend:5003) ──
73
  echo "[startup] Starting nginx on port 7860..."
74
  nginx
75
 
frontend/frontend.py CHANGED
@@ -7,7 +7,7 @@ import json, time, os
7
  from shared.config import Config
8
  from shared.kafka_utils import create_producer
9
 
10
- app = Flask(__name__, template_folder='templates')
11
 
12
  producer = create_producer(component_name="Frontend")
13
 
 
7
  from shared.config import Config
8
  from shared.kafka_utils import create_producer
9
 
10
+ app = Flask(__name__, template_folder=os.getenv("TEMPLATE_FOLDER", "templates"))
11
 
12
  producer = create_producer(component_name="Frontend")
13
 
nginx.conf CHANGED
@@ -20,6 +20,18 @@ http {
20
  chunked_transfer_encoding on;
21
  }
22
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  # FIX UI Client – served under /fix/
24
  location /fix/ {
25
  proxy_pass http://localhost:5002/;
 
20
  chunked_transfer_encoding on;
21
  }
22
 
23
+ # Frontend (order entry) – served under /frontend/
24
+ location /frontend/ {
25
+ proxy_pass http://localhost:5003/;
26
+ proxy_set_header Host $host;
27
+ proxy_set_header X-Real-IP $remote_addr;
28
+ sub_filter 'href="/' 'href="/frontend/';
29
+ sub_filter 'action="/' 'action="/frontend/';
30
+ sub_filter_once off;
31
+ sub_filter_types text/html;
32
+ proxy_redirect / /frontend/;
33
+ }
34
+
35
  # FIX UI Client – served under /fix/
36
  location /fix/ {
37
  proxy_pass http://localhost:5002/;