ShadowBroker — OSINT Geospatial Intelligence Platform¶
Repo: github.com/BigBodyCobain/Shadowbroker
Host: SRV1 (10.0.20.30)
Path: /opt/projects/shadowbroker
Deploy: Docker Compose (frontend + backend)
Access: http://10.0.20.30:3000 (local), via tunnel at https://shadowbroker.gntech.me
Architecture¶
[Browser] ──▶ shadowbroker-frontend (:3000)
│
http://backend:8000 (Docker bridge)
│
shadowbroker-backend (:8000)
│
┌─────┴─────┐
│ backend │
│ data vol │
└───────────┘
- Backend: FastAPI (Python), 4G memory limit, 2 CPU cores
- Frontend: Next.js, 512M memory limit
- Data: Docker volume
backend_dataat/app/data
Requirements¶
- Docker + Docker Compose
- Registered accounts for full data:
- OpenSky Network — free registration for full aircraft telemetry
- AIS API key — maritime vessel tracking
- Various optional API keys (see
.env.example)
Deployment Steps¶
Step 1 — Clone repo¶
git clone https://github.com/BigBodyCobain/Shadowbroker.git /opt/projects/shadowbroker
cd /opt/projects/shadowbroker
Step 2 — Configure environment¶
cp .env.example /opt/projects/shadowbroker/.env
nano /opt/projects/shadowbroker/.env
Set at minimum:
OPENSKY_CLIENT_ID=your_opensky_username
OPENSKY_CLIENT_SECRET=your_opensky_password
AIS_API_KEY=your_ais_key
ADMIN_KEY=choose_a_secure_admin_key
Step 3 — Start containers¶
cd /opt/projects/shadowbroker
docker compose up -d
Both containers bind to 127.0.0.1 by default (localhost-only).
Step 4 — Verify¶
docker compose ps
curl http://127.0.0.1:8000/api/health
# Open http://YOUR_HOST_IP:3000 in browser
Systemd Service (Auto-start on Boot)¶
A systemd oneshot service keeps ShadowBroker running across reboots:
File: /etc/systemd/system/shadowbroker.service
[Unit]
Description=ShadowBroker OSINT Platform (Docker Compose)
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/projects/shadowbroker
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
StandardOutput=journal
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable shadowbroker.service
Management¶
# Status
docker compose ps
# Logs
docker compose logs -f
docker compose logs -f backend
docker compose logs -f frontend
# Restart
docker compose restart backend
# Full stop
docker compose down
# Update (pull latest + recreate)
docker compose pull
docker compose up -d
Current Config¶
- Bind:
127.0.0.1(loopback) — accessible locally, exposed via Cloudflare Tunnel - Frontend port:
3000 - Backend port:
8000 - Memory limits: backend 4G, frontend 512M
- CORS: auto-detects LAN IPs (empty override)
- Mesh (Reticulum / Infonet): disabled by default
Troubleshooting¶
Backend OOM (Out of Memory)¶
The backend aggregates heavy geospatial feeds (AIS, OpenSky, satellites, threat feeds). If it crashes:
docker compose logs backend | grep -i "killed\|oom\|memory"
docker compose up -d # restart
Increase memory limit in .env:
BACKEND_MEMORY_LIMIT=6G
Frontend won't connect¶
# Check backend health
curl http://127.0.0.1:8000/api/health
# Check frontend if it can reach backend
docker compose exec frontend curl -s http://backend:8000/api/health | head -5
Empty layers (no aircraft, ships, etc.)¶
Check API keys in .env — OpenSky and AIS are required for most data. Without them, the map will be largely empty.
Can't reach from another device¶
Both containers bind to 127.0.0.1 by default. To expose on the LAN, set in .env:
BIND=0.0.0.0
docker compose up -d to recreate. For production access, prefer a reverse proxy or tunnel instead.