Skip to content

Commit 79b3557

Browse files
challgrenclaude
andcommitted
Fix reverse proxy subpath mounting support
- Added dynamic base URL detection in JavaScript - Changed navigation links to relative paths - Updated API calls to use detected base URL - Fixed routing for /circles/ subpath mounting - Added nginx proxy configuration example - Tested with simulated reverse proxy setup The application now works correctly whether accessed: - Directly at root (http://localhost:8888/) - Through reverse proxy at subpath (http://server/circles/) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent ca471e1 commit 79b3557

3 files changed

Lines changed: 46 additions & 13 deletions

File tree

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ ENV PUID=1000 \
1515
UPDATE_INTERVAL=5 \
1616
SHOW_ALL_AIRCRAFT=true \
1717
SHOW_TRACKS=true \
18-
MAX_TRACK_POINTS=50
18+
MAX_TRACK_POINTS=50 \
19+
URL_PREFIX=""
1920

2021
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
2122

README.md

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,25 @@ Access at: `http://localhost:8888/history`
175175

176176
### Reverse Proxy Support
177177

178-
The application works seamlessly behind reverse proxies like `ghcr.io/sdr-enthusiasts/docker-reversewebproxy`. The Flask application automatically handles:
178+
The application works seamlessly behind reverse proxies including when mounted at a subpath. The application automatically detects its base URL and adjusts all links and API calls accordingly.
179179

180-
- `X-Forwarded-For` - Client IP addresses
181-
- `X-Forwarded-Proto` - HTTP/HTTPS protocol
182-
- `X-Forwarded-Host` - Original hostname
183-
- `X-Forwarded-Prefix` - URL path prefix
180+
#### Nginx Configuration Example
181+
182+
For mounting at `/circles/`:
183+
184+
```nginx
185+
location /circles/ {
186+
proxy_pass http://aircraft-circle:8888/;
187+
proxy_set_header Upgrade $http_upgrade;
188+
proxy_set_header Connection $http_connection;
189+
proxy_set_header Host $http_host;
190+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
191+
proxy_set_header X-Forwarded-Proto $scheme;
192+
proxy_redirect / /circles/;
193+
}
194+
```
184195

185-
Example reverse proxy configuration:
196+
#### Docker Compose with sdr-enthusiasts/docker-reversewebproxy
186197

187198
```yaml
188199
services:
@@ -200,6 +211,15 @@ services:
200211
- TAR1090_URL=http://tar1090:80
201212
```
202213
214+
The application automatically handles:
215+
216+
- `X-Forwarded-For` - Client IP addresses
217+
- `X-Forwarded-Proto` - HTTP/HTTPS protocol
218+
- `X-Forwarded-Host` - Original hostname
219+
- `X-Forwarded-Prefix` - URL path prefix
220+
- Relative URLs for all navigation and API calls
221+
- Automatic base URL detection for subpath mounting
222+
203223
- Filter by date range, pattern type, and callsign
204224
- Visual timeline of detection activity
205225
- Direct links to TAR1090 replay for each pattern

app.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
1616
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
1717
<script>
18+
// Get base URL for API calls (handles reverse proxy scenarios)
19+
// This works whether we're at root (/) or a subpath (/circles/)
20+
const currentPath = window.location.pathname;
21+
const baseUrl = currentPath.endsWith('/') ? currentPath.slice(0, -1) : currentPath.replace(/\\/[^/]*$/, '');
22+
1823
// Aircraft icon shapes from tar1090 - embedded directly to avoid loading issues
1924
const aircraftShapes = {
2025
'airliner': {
@@ -205,8 +210,8 @@
205210
<div class="header">
206211
<h1>✈️ Aircraft Pattern Detector - Live View</h1>
207212
<div class="nav-links">
208-
<a href="/" class="active">Live View</a>
209-
<a href="/history">History</a>
213+
<a href="." class="active">Live View</a>
214+
<a href="history">History</a>
210215
</div>
211216
</div>
212217
@@ -408,7 +413,7 @@
408413
// Update patterns from API
409414
async function updatePatterns() {
410415
try {
411-
const response = await fetch('/api/patterns');
416+
const response = await fetch(baseUrl + '/api/patterns');
412417
const data = await response.json();
413418
414419
// Debug logging
@@ -718,6 +723,13 @@
718723
<meta name="viewport" content="width=device-width, initial-scale=1.0">
719724
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
720725
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
726+
<script>
727+
// Get base URL for API calls (handles reverse proxy scenarios)
728+
const currentPath = window.location.pathname;
729+
const baseUrl = currentPath.endsWith('/history') ?
730+
currentPath.slice(0, -8) : // Remove '/history'
731+
(currentPath.endsWith('/') ? currentPath.slice(0, -1) : currentPath.replace(/\\/[^/]*$/, ''));
732+
</script>
721733
<script>
722734
// Aircraft icon shapes from tar1090 - embedded directly to avoid loading issues
723735
const aircraftShapes = {
@@ -985,8 +997,8 @@
985997
<div class="header">
986998
<h1>✈️ Pattern Detection History</h1>
987999
<div class="nav-links">
988-
<a href="/">Live View</a>
989-
<a href="/history" class="active">History</a>
1000+
<a href=".">Live View</a>
1001+
<a href="history" class="active">History</a>
9901002
</div>
9911003
</div>
9921004
@@ -1094,7 +1106,7 @@
10941106
// Load history data
10951107
async function loadHistory() {
10961108
try {
1097-
const response = await fetch('/api/history');
1109+
const response = await fetch(baseUrl + '/api/history');
10981110
const data = await response.json();
10991111
11001112
allCircles = data.circles || [];

0 commit comments

Comments
 (0)