Skip to content

Commit 7bf2e9a

Browse files
committed
Implement dynamic URL detection for true deployment portability
Replace hardcoded environment variables with runtime URL detection using window.location.origin. This eliminates the need for environment-specific builds and makes the panel deployable anywhere. Key improvements: - Panel API URLs auto-detected from current domain in production - Wallet service URLs auto-detected from current domain in production - Relay WebSocket URLs auto-detected from current domain in production - One build now works on ANY domain (localhost, custom domains, ngrok tunnels) - No more REACT_APP_BASE_URL or REACT_APP_WALLET_BASE_URL needed in production - Simplified deployment process with minimal environment configuration - Updated README with comprehensive deployment guidance and launch-ready improvements Production URLs now resolve to: - Panel API: ${window.location.origin}/panel - Wallet API: ${window.location.origin}/wallet - Relay WebSocket: wss://${window.location.host} Development mode still uses localhost URLs for easy local development.
1 parent 24f4148 commit 7bf2e9a

2 files changed

Lines changed: 167 additions & 40 deletions

File tree

README.md

Lines changed: 127 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44

55
This repository is home to the hornet storage panel which is a typescript / react web application designed for managing a hornet storage nostr multimedia relay which can be found here: https://github.com/HORNET-Storage/HORNETS-Nostr-Relay
66

7+
## ⚡ What You Need Before Starting
8+
9+
**Before installing, ensure you have:**
10+
1. **A Nostr browser extension** ([Alby](https://getalby.com/), [nos2x](https://github.com/fiatjaf/nos2x), etc.) - **REQUIRED**
11+
2. **Node.js 16+** and **yarn** installed
12+
3. **The HORNETS relay service** running (see [here](https://github.com/HORNET-Storage/HORNETS-Nostr-Relay))
13+
14+
**Without these, the panel will not function.**
15+
716
### Live Demo
817
We have a live demo that can be found at http://hornetstorage.net for anyone that wants to see what the panel looks like.
918

@@ -14,6 +23,36 @@ We have a live demo that can be found at http://hornetstorage.net for anyone tha
1423
- Choose which supported transport protocols to enable such as libp2p and websockets
1524
- Enable / disable which media extensions are accepted by the relay such as png and mp4
1625
- View statistics about stored notes and media
26+
- Upload relay icons with integrated Blossom server support
27+
28+
## 🔑 Important Prerequisites
29+
30+
### NIP-07 Browser Extension Required
31+
**The HORNETS Relay Panel requires a NIP-07 compatible Nostr browser extension to function.**
32+
33+
You must install one of these browser extensions before using the panel:
34+
- **[Alby](https://getalby.com/)** - Bitcoin Lightning & Nostr browser extension
35+
- **[nos2x](https://github.com/fiatjaf/nos2x)** - Simple Nostr browser extension
36+
- **[Flamingo](https://flamingo.me/)** - Nostr browser extension
37+
- **[Horse](https://github.com/freakonometrics/horse)** - Nostr browser extension
38+
39+
The panel uses **NIP-07** ([window.nostr capability](https://nostr-nips.com/nip-07)) for:
40+
- User authentication and login
41+
- Event signing for relay configuration
42+
- File uploads with cryptographic verification
43+
44+
**📖 Learn more about NIP-07**: [https://nostr-nips.com/nip-07](https://nostr-nips.com/nip-07)
45+
46+
## 🚀 Quick Start
47+
48+
**Essential steps to get running:**
49+
50+
1. **Install a NIP-07 browser extension** (required - see above)
51+
2. **Install dependencies**: `npm install -g serve` and `yarn install`
52+
3. **Start development**: `yarn start`
53+
4. **For production**: `yarn build` then `serve -s build`
54+
55+
**For full deployment with reverse proxy, see the detailed setup guide below.**
1756

1857
## Previews
1958
*All preview images are taken from the live demo*
@@ -32,18 +71,18 @@ We have a live demo that can be found at http://hornetstorage.net for anyone tha
3271

3372
The HORNETS Relay Panel is built with a microservices architecture comprising:
3473

35-
### Services
74+
### Services & Dependencies
3675
- **Frontend (React App)**: Port 3000 (dev) - The admin dashboard interface
3776
- **Panel API**: Port 9002 - Backend service for panel operations
38-
- **Relay Service**: Port 9001 - WebSocket service for Nostr relay functionality
39-
- **Wallet Service**: Port 9003 - Backend service for wallet operations
40-
- **Transcribe API**: Port 8000 - Service for transcription features
77+
- **[Relay Service](https://github.com/HORNET-Storage/HORNETS-Nostr-Relay)**: Port 9001 - WebSocket service for Nostr relay functionality
78+
- **[Wallet Service](https://github.com/HORNET-Storage/Super-Neutrino-Wallet)**: Port 9003 - Backend service for wallet operations
79+
- **[Media Moderation](https://github.com/HORNET-Storage/NestShield)**: Port 8000 - Content moderation and filtering service
4180

4281
### Reverse Proxy Architecture
4382
```
4483
Client Request
4584
46-
Nginx (Port 80/443)
85+
Nginx (Port 80/443)
4786
4887
┌─────────────────────────────────────────────────────────────┐
4988
│ Route Distribution: │
@@ -52,8 +91,8 @@ Nginx (Port 80/443)
5291
│ │ (Port 9001) │ │ (Port 3000) │ │ (Port 9002) │ │
5392
│ └─────────────────┘ └─────────────────┘ └──────────────┘ │
5493
│ ┌─────────────────┐ ┌─────────────────┐ │
55-
│ │ /wallet/ → Wallet│ │/transcribe/ → API│
56-
│ │ (Port 9003) │ │ (Port 8000) │
94+
│ │ /wallet/ → Wallet│ │/moderate/ → Media│
95+
│ │ (Port 9003) │ │ (Port 8000) │ │
5796
│ └─────────────────┘ └─────────────────┘ │
5897
└─────────────────────────────────────────────────────────────┘
5998
```
@@ -82,12 +121,16 @@ While possible, direct port access has limitations:
82121
- [Node.js](https://nodejs.org/en/) version **>=16.0.0**
83122
- [Yarn](https://yarnpkg.com/) package manager
84123
- [Git](https://git-scm.com/) for version control
124+
- **[serve](https://www.npmjs.com/package/serve)** for production builds: `npm install -g serve`
85125

86126
### Optional (For Production)
87-
- [Nginx](https://nginx.org/) for reverse proxy
127+
- [Nginx](https://nginx.org/) for reverse proxy *(Linux server configuration)*
88128
- SSL certificate (Let's Encrypt recommended)
89129
- Domain name
90130

131+
### Browser Requirements
132+
- **NIP-07 compatible browser extension** (see Important Prerequisites section above)
133+
91134
## 🛠️ Installation & Setup
92135

93136
### 1. Clone the Repository
@@ -113,28 +156,34 @@ REACT_APP_DEMO_MODE=false
113156
```
114157

115158
#### Production Setup
116-
Copy the example environment file and customize:
159+
For production, minimal environment configuration is needed thanks to **dynamic URL detection**:
160+
117161
```bash
118162
cp .env.production.example .env.production
119163
```
120164

121-
Edit `.env.production` with your actual values:
165+
Edit `.env.production` (most values are now auto-detected):
122166
```env
123-
# Production Environment Configuration
124-
REACT_APP_BASE_URL=https://your-domain.com/panel
125-
REACT_APP_WALLET_BASE_URL=https://your-domain.com/wallet
126-
REACT_APP_ASSETS_BUCKET=https://your-domain.com
127-
REACT_APP_DEMO_MODE=false
128-
129167
# Router configuration for reverse proxy
130168
REACT_APP_BASENAME=/front
131169
PUBLIC_URL=/front
132170
171+
# Optional: Demo mode (defaults to false)
172+
REACT_APP_DEMO_MODE=false
173+
174+
# Optional: Custom Nostr relay URLs (defaults to popular relays)
175+
# REACT_APP_NOSTR_RELAY_URLS=wss://relay.damus.io,wss://relay.nostr.band
176+
133177
# Development optimizations
134178
ESLINT_NO_DEV_ERRORS=true
135179
TSC_COMPILE_ON_ERROR=true
136180
```
137181

182+
**🎯 Key Improvement**: The panel now **automatically detects** API URLs from `window.location.origin`, meaning:
183+
-**No need to specify `REACT_APP_BASE_URL` or `REACT_APP_WALLET_BASE_URL`**
184+
-**Same build works on ANY domain** (localhost, your-domain.com, ngrok tunnels, etc.)
185+
-**No environment-specific rebuilds required**
186+
138187
### 4. Start Development Server
139188

140189
#### Using yarn (standard)
@@ -200,10 +249,20 @@ server {
200249
proxy_pass http://127.0.0.1:9003;
201250
}
202251
252+
# Media moderation service (optional)
253+
location /moderate/ {
254+
rewrite ^/moderate/(.*)$ /$1 break;
255+
proxy_pass http://127.0.0.1:8000;
256+
}
257+
203258
# Frontend React app
204259
location /front/ {
205260
rewrite ^/front/(.*)$ /$1 break;
206-
proxy_pass http://127.0.0.1:3000; # Or serve static files
261+
proxy_pass http://127.0.0.1:3000; # Development: proxy to dev server
262+
263+
# Production: Serve static files instead (uncomment and comment above)
264+
# try_files $uri $uri/ /front/index.html;
265+
# root /var/www/html; # Path to your built files
207266
}
208267
209268
# Default location - Relay service with WebSocket support
@@ -249,10 +308,10 @@ sudo cp -r build/* /var/www/html/front/
249308
Ensure all backend services are running:
250309
```bash
251310
# Start in order of dependency
252-
./relay-service & # Port 9001
253-
./panel-api & # Port 9002
254-
./wallet-service & # Port 9003
255-
./transcribe-api & # Port 8000
311+
./relay-service & # Port 9001
312+
./panel-api & # Port 9002
313+
./wallet-service & # Port 9003
314+
./media-moderation & # Port 8000 (optional)
256315
```
257316

258317
#### Step 5: Start Nginx
@@ -268,8 +327,7 @@ Update `.env.production`:
268327
```env
269328
REACT_APP_BASENAME=
270329
PUBLIC_URL=
271-
REACT_APP_BASE_URL=http://localhost:9002
272-
REACT_APP_WALLET_BASE_URL=http://localhost:9003
330+
# Note: API URLs are now auto-detected, no need to specify them!
273331
```
274332

275333
#### Step 2: Build and Serve
@@ -303,24 +361,34 @@ ngrok http 3000
303361
```
304362

305363
### Environment Variables for Tunneling
306-
When using tunnels, update your `.env.production`:
307-
```env
308-
REACT_APP_BASE_URL=https://your-tunnel-url.com/panel
309-
REACT_APP_WALLET_BASE_URL=https://your-tunnel-url.com/wallet
310-
```
364+
**Great news!** Thanks to dynamic URL detection, **no environment variable changes are needed** when using tunnels. The panel automatically adapts to any domain:
365+
366+
-`ngrok http 80` → Panel works immediately at `https://abc123.ngrok.io/front/`
367+
- ✅ Custom domain tunnel → Panel works immediately
368+
- ✅ Any hosting provider → Panel works immediately
369+
370+
**No rebuilds or environment changes required!**
311371

312372
## 🔧 Configuration Options
313373

374+
> **🚀 Major Improvement**: The panel now uses **dynamic URL detection** instead of hardcoded environment variables. This means **one build works everywhere** - no more environment-specific builds or complex URL configuration!
375+
314376
### REACT_APP_BASENAME
315377
Controls where the React app is served from:
316378
- `/front` - App accessible at `https://domain.com/front/`
317379
- `/admin` - App accessible at `https://domain.com/admin/`
318380
- `` (empty) - App accessible at `https://domain.com/`
319381

320382
### Service URLs
321-
- **REACT_APP_BASE_URL**: Panel API endpoint
322-
- **REACT_APP_WALLET_BASE_URL**: Wallet service endpoint
323-
- **REACT_APP_ASSETS_BUCKET**: Static assets URL
383+
**🎯 Auto-Detection**: Service URLs are now automatically detected in production:
384+
- **Panel API**: `${window.location.origin}/panel` (auto-detected)
385+
- **Wallet Service**: `${window.location.origin}/wallet` (auto-detected)
386+
- **Relay WebSocket**: `wss://${window.location.host}` (auto-detected)
387+
388+
**Manual Override** (development only):
389+
- **REACT_APP_BASE_URL**: Panel API endpoint (dev mode only)
390+
- **REACT_APP_WALLET_BASE_URL**: Wallet service endpoint (dev mode only)
391+
- **REACT_APP_NOSTR_RELAY_URLS**: Additional Nostr relays (optional)
324392

325393
### Demo Mode
326394
Set `REACT_APP_DEMO_MODE=true` to enable demo functionality with mock data.
@@ -344,6 +412,27 @@ export NODE_OPTIONS="--openssl-legacy-provider --max-old-space-size=4096"
344412
**Error**: Network errors or 404s
345413
**Solution**: Verify service URLs in environment variables and ensure backend services are running.
346414

415+
#### 3.1. CORS Configuration Issues
416+
**Error**: `Access to fetch at 'X' from origin 'Y' has been blocked by CORS policy`
417+
**Solution**: Ensure your backend services are configured to accept requests from your frontend origin:
418+
419+
For development with direct access:
420+
```env
421+
# Frontend running on http://localhost:3000
422+
# Backend services must allow this origin in their CORS configuration
423+
REACT_APP_BASE_URL=http://localhost:9002
424+
REACT_APP_WALLET_BASE_URL=http://localhost:9003
425+
```
426+
427+
For production with reverse proxy (recommended):
428+
```env
429+
# All services behind same domain - no CORS issues
430+
REACT_APP_BASE_URL=https://your-domain.com/panel
431+
REACT_APP_WALLET_BASE_URL=https://your-domain.com/wallet
432+
```
433+
434+
**Note**: When using direct port access, each backend service must be configured to allow your frontend's origin in their CORS settings. Using a reverse proxy eliminates CORS issues entirely.
435+
347436
#### 4. Routing Issues with Reverse Proxy
348437
**Error**: 404 on refresh or direct URL access
349438
**Solution**: Configure nginx to handle React Router:
@@ -366,7 +455,7 @@ Start services in this order:
366455
1. Relay Service (Port 9001) - Core WebSocket functionality
367456
2. Panel API (Port 9002) - Main backend
368457
3. Wallet Service (Port 9003) - Payment processing
369-
4. Transcribe API (Port 8000) - Additional features
458+
4. Media Moderation (Port 8000) - Content filtering (optional)
370459
5. Frontend (Port 3000) - User interface
371460

372461
### Health Checks
@@ -454,4 +543,9 @@ For issues and support:
454543

455544
---
456545

457-
**Note**: This panel is designed to work with the [HORNETS Nostr Relay](https://github.com/HORNET-Storage/HORNETS-Nostr-Relay). Ensure you have the relay service running for full functionality.
546+
**Note**: This panel is designed to work with the HORNETS Storage ecosystem:
547+
- **[HORNETS Nostr Relay](https://github.com/HORNET-Storage/HORNETS-Nostr-Relay)** - Core relay service (required)
548+
- **[Super Neutrino Wallet](https://github.com/HORNET-Storage/Super-Neutrino-Wallet)** - Payment processing (required for paid features)
549+
- **[NestShield](https://github.com/HORNET-Storage/NestShield)** - Media moderation service (optional)
550+
551+
Ensure you have at minimum the relay service running for basic functionality.

src/config/config.ts

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,41 @@
11
// config.ts
2+
3+
// Dynamic URL detection - panel works from anywhere!
4+
const getBaseURL = (): string => {
5+
// Demo mode override for testing
6+
if (process.env.REACT_APP_DEMO_MODE === 'true') {
7+
return 'http://localhost:10002';
8+
}
9+
10+
// Development mode - use localhost
11+
if (process.env.NODE_ENV === 'development') {
12+
return process.env.REACT_APP_BASE_URL || 'http://localhost:9002';
13+
}
14+
15+
// Production - use current origin + /panel path
16+
// This makes the panel work from ANY domain without rebuilding
17+
return `${window.location.origin}/panel`;
18+
};
19+
20+
const getWalletURL = (): string => {
21+
// Demo mode override for testing
22+
if (process.env.REACT_APP_DEMO_MODE === 'true') {
23+
return 'http://localhost:9003';
24+
}
25+
26+
// Development mode - use localhost
27+
if (process.env.NODE_ENV === 'development') {
28+
return process.env.REACT_APP_WALLET_BASE_URL?.trim() || 'http://localhost:9003';
29+
}
30+
31+
// Production - use current origin + /wallet path
32+
return `${window.location.origin}/wallet`;
33+
};
34+
235
const config = {
3-
baseURL: process.env.REACT_APP_DEMO_MODE === 'true'
4-
? 'http://localhost:10002'
5-
: process.env.NODE_ENV === 'production'
6-
? process.env.REACT_APP_BASE_URL || 'http://localhost:9002'
7-
: process.env.REACT_APP_BASE_URL || 'http://localhost:9002',
36+
baseURL: getBaseURL(),
837
isDemoMode: process.env.REACT_APP_DEMO_MODE === 'true',
9-
walletBaseURL: process.env.REACT_APP_WALLET_BASE_URL?.trim() || 'http://localhost:9003',
38+
walletBaseURL: getWalletURL(),
1039

1140
// Nostr relay configuration
1241
nostrRelayUrls: process.env.REACT_APP_NOSTR_RELAY_URLS?.split(',').map(url => url.trim()) || [
@@ -17,7 +46,11 @@ const config = {
1746
],
1847

1948
// User's own relay URL (primary relay for profile fetching)
20-
ownRelayUrl: process.env.REACT_APP_OWN_RELAY_URL?.trim() || null,
49+
// In production, use the current domain as the relay WebSocket URL
50+
ownRelayUrl: process.env.REACT_APP_OWN_RELAY_URL?.trim() ||
51+
(process.env.NODE_ENV === 'production'
52+
? `${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//${window.location.host}`
53+
: null),
2154

2255
// Notification settings
2356
notifications: {

0 commit comments

Comments
 (0)