somratpro Claude Sonnet 4.6 commited on
Commit
eb3a3f8
Β·
1 Parent(s): 6d97584

Fix routing, ECONNREFUSED, and Cloudflare setup

Browse files

- Move dashboard to /_status, proxy / root directly to Paperclip
(fixes "Company not found APP" β€” SPA no longer sees /app/ prefix)
- Hardcode PAPERCLIP_HOST to 127.0.0.1 instead of reading HOST env
(fixes ECONNREFUSED 0.0.0.0:3100 β€” 0.0.0.0 is bind-only)
- Remove CLOUDFLARE_ACCOUNT_ID requirement from setup condition
(setup script already auto-discovers account ID)
- Source CF proxy env file after setup so CLOUDFLARE_PROXY_URL/SECRET
reach the Node process

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

Files changed (3) hide show
  1. README.md +4 -4
  2. health-server.js +11 -35
  3. start.sh +10 -3
README.md CHANGED
@@ -185,7 +185,7 @@ docker-compose up -d
185
 
186
  ### Dashboard
187
 
188
- Access the health monitoring dashboard at: `http://your-space-url/`
189
 
190
  **Shows:**
191
 
@@ -196,7 +196,7 @@ Access the health monitoring dashboard at: `http://your-space-url/`
196
 
197
  ### Paperclip UI
198
 
199
- Full Paperclip interface at: `http://your-space-url/app/`
200
 
201
  **Features:**
202
 
@@ -277,7 +277,7 @@ python3 /app/paperclip-sync.py restore
277
 
278
  ### Paperclip Not Accessible
279
 
280
- **Problem**: Can't reach <http://localhost:7861/app/>
281
 
282
  **Solution:**
283
 
@@ -345,7 +345,7 @@ python3 /app/paperclip-sync.py restore
345
 
346
  ```
347
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
348
- β”‚ Paperclip UI β”‚ (http://space-url/app/)
349
  β”‚ & REST API β”‚
350
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
351
  β”‚
 
185
 
186
  ### Dashboard
187
 
188
+ Access the health monitoring dashboard at: `http://your-space-url/_status`
189
 
190
  **Shows:**
191
 
 
196
 
197
  ### Paperclip UI
198
 
199
+ Full Paperclip interface at: `http://your-space-url/`
200
 
201
  **Features:**
202
 
 
277
 
278
  ### Paperclip Not Accessible
279
 
280
+ **Problem**: Can't reach <http://localhost:7861/>
281
 
282
  **Solution:**
283
 
 
345
 
346
  ```
347
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
348
+ β”‚ Paperclip UI β”‚ (http://space-url/)
349
  β”‚ & REST API β”‚
350
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
351
  β”‚
health-server.js CHANGED
@@ -9,7 +9,7 @@ const net = require("net");
9
 
10
  const app = express();
11
  const PORT = 7861; // always public-facing port, never read from PORT (that's for Paperclip)
12
- const PAPERCLIP_HOST = process.env.HOST || "127.0.0.1";
13
  const PAPERCLIP_PORT = 3100;
14
 
15
  // Middleware
@@ -84,14 +84,18 @@ app.get("/health", async (req, res) => {
84
  // ============================================================================
85
  // Dashboard Route
86
  // ============================================================================
87
- app.get("/", (req, res) => {
88
  res.send(getDashboardHTML());
89
  });
90
 
91
- app.get("/dashboard/", (req, res) => {
92
  res.send(getDashboardHTML());
93
  });
94
 
 
 
 
 
95
  app.get("/dashboard/status", (req, res) => {
96
  const syncStatus = readSyncStatus();
97
  const uptime = process.uptime();
@@ -132,34 +136,6 @@ app.post("/dashboard/uptimerobot/setup", (req, res) => {
132
  // Reverse Proxy Routes
133
  // ============================================================================
134
 
135
- // Proxy all /app/* requests to Paperclip
136
- app.all("/app/*", async (req, res) => {
137
- const targetPath = req.path.replace("/app", "") || "/";
138
- const targetUrl = `http://${PAPERCLIP_HOST}:${PAPERCLIP_PORT}${targetPath}`;
139
-
140
- try {
141
- const response = await proxyRequest(
142
- req.method,
143
- targetUrl,
144
- req.headers,
145
- req.body,
146
- );
147
-
148
- // Copy response headers
149
- Object.keys(response.headers).forEach((key) => {
150
- res.setHeader(key, response.headers[key]);
151
- });
152
-
153
- res.status(response.statusCode).send(response.body);
154
- } catch (error) {
155
- console.error(`Proxy error: ${error.message}`);
156
- res.status(503).json({
157
- error: "Paperclip service unavailable",
158
- details: error.message,
159
- });
160
- }
161
- });
162
-
163
  // Proxy all /api/* requests to Paperclip
164
  app.all("/api/*", async (req, res) => {
165
  const targetPath = req.path;
@@ -623,10 +599,10 @@ function getDashboardHTML() {
623
  </div>
624
  <div class="stat">
625
  <span class="stat-label">UI URL</span>
626
- <span class="stat-value"><span class="code">/app/</span></span>
627
  </div>
628
  <div class="button-group">
629
- <a href="/app/" class="button button-primary" target="_blank">Open Paperclip UI</a>
630
  </div>
631
  </div>
632
 
@@ -684,7 +660,7 @@ function getDashboardHTML() {
684
  <div class="card">
685
  <h2>πŸ“š Resources</h2>
686
  <div class="button-group" style="flex-direction: column;">
687
- <a href="/app/" class="button button-primary" target="_blank">Paperclip Dashboard</a>
688
  <a href="/api/" class="button button-secondary" target="_blank">API Reference</a>
689
  </div>
690
  <div class="stat" style="margin-top: 16px;">
@@ -819,5 +795,5 @@ server.listen(PORT, "0.0.0.0", () => {
819
  console.log(`βœ“ Health server listening on port ${PORT}`);
820
  console.log(`βœ“ Dashboard: http://localhost:${PORT}/`);
821
  console.log(`βœ“ API proxy: http://localhost:${PORT}/api/*`);
822
- console.log(`βœ“ App proxy: http://localhost:${PORT}/app/`);
823
  });
 
9
 
10
  const app = express();
11
  const PORT = 7861; // always public-facing port, never read from PORT (that's for Paperclip)
12
+ const PAPERCLIP_HOST = "127.0.0.1";
13
  const PAPERCLIP_PORT = 3100;
14
 
15
  // Middleware
 
84
  // ============================================================================
85
  // Dashboard Route
86
  // ============================================================================
87
+ app.get("/_status", (req, res) => {
88
  res.send(getDashboardHTML());
89
  });
90
 
91
+ app.get("/_status/", (req, res) => {
92
  res.send(getDashboardHTML());
93
  });
94
 
95
+ app.get("/dashboard/", (req, res) => {
96
+ res.redirect("/_status");
97
+ });
98
+
99
  app.get("/dashboard/status", (req, res) => {
100
  const syncStatus = readSyncStatus();
101
  const uptime = process.uptime();
 
136
  // Reverse Proxy Routes
137
  // ============================================================================
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  // Proxy all /api/* requests to Paperclip
140
  app.all("/api/*", async (req, res) => {
141
  const targetPath = req.path;
 
599
  </div>
600
  <div class="stat">
601
  <span class="stat-label">UI URL</span>
602
+ <span class="stat-value"><span class="code">/</span></span>
603
  </div>
604
  <div class="button-group">
605
+ <a href="/" class="button button-primary" target="_blank">Open Paperclip UI</a>
606
  </div>
607
  </div>
608
 
 
660
  <div class="card">
661
  <h2>πŸ“š Resources</h2>
662
  <div class="button-group" style="flex-direction: column;">
663
+ <a href="/" class="button button-primary" target="_blank">Paperclip Dashboard</a>
664
  <a href="/api/" class="button button-secondary" target="_blank">API Reference</a>
665
  </div>
666
  <div class="stat" style="margin-top: 16px;">
 
795
  console.log(`βœ“ Health server listening on port ${PORT}`);
796
  console.log(`βœ“ Dashboard: http://localhost:${PORT}/`);
797
  console.log(`βœ“ API proxy: http://localhost:${PORT}/api/*`);
798
+ console.log(`βœ“ App proxy: http://localhost:${PORT}/ (root β†’ Paperclip)`);
799
  });
start.sh CHANGED
@@ -112,11 +112,18 @@ else
112
  fi
113
 
114
  # ── Cloudflare Proxy ──────────────────────────────────────────────────────────
115
- if [ -n "${CLOUDFLARE_WORKERS_TOKEN:-}" ] && [ -n "${CLOUDFLARE_ACCOUNT_ID:-}" ]; then
116
  echo "Setting up Cloudflare proxy..."
117
  python3 /app/cloudflare-proxy-setup.py 2>&1 || echo "Cloudflare setup failed, continuing without proxy"
118
  fi
119
 
 
 
 
 
 
 
 
120
  # ── Load Cloudflare module if present ─────────────────────────────────────────
121
  if [ -f /app/cloudflare-proxy.js ]; then
122
  export NODE_OPTIONS="--require /app/cloudflare-proxy.js"
@@ -251,8 +258,8 @@ fi
251
 
252
  echo "HuggingClip is ready!"
253
  echo ""
254
- echo " Health dashboard : http://localhost:7861/"
255
- echo " Paperclip UI : http://localhost:7861/app/"
256
  echo " API : http://localhost:7861/api/"
257
  echo ""
258
 
 
112
  fi
113
 
114
  # ── Cloudflare Proxy ──────────────────────────────────────────────────────────
115
+ if [ -n "${CLOUDFLARE_WORKERS_TOKEN:-}" ]; then
116
  echo "Setting up Cloudflare proxy..."
117
  python3 /app/cloudflare-proxy-setup.py 2>&1 || echo "Cloudflare setup failed, continuing without proxy"
118
  fi
119
 
120
+ # Source CF proxy env if the setup script wrote it (provides CLOUDFLARE_PROXY_URL + SECRET)
121
+ _CF_ENV="/tmp/huggingclaw-cloudflare-proxy.env"
122
+ if [ -f "${_CF_ENV}" ]; then
123
+ # shellcheck source=/dev/null
124
+ . "${_CF_ENV}"
125
+ fi
126
+
127
  # ── Load Cloudflare module if present ─────────────────────────────────────────
128
  if [ -f /app/cloudflare-proxy.js ]; then
129
  export NODE_OPTIONS="--require /app/cloudflare-proxy.js"
 
258
 
259
  echo "HuggingClip is ready!"
260
  echo ""
261
+ echo " Health dashboard : http://localhost:7861/_status"
262
+ echo " Paperclip UI : http://localhost:7861/"
263
  echo " API : http://localhost:7861/api/"
264
  echo ""
265