Hub Deployment
The hub is the central component of BirdNET-NG: an API gateway, MQTT ingester, job queue manager, and web UI host. It runs as an 8-container Docker Compose stack behind a Traefik reverse proxy.
What the Hub Does
- API gateway (Fastify) — serves the REST API for web and mobile clients, handles JWT and API key auth
- MQTT ingester — receives audio chunks and telemetry from satellites via Mosquitto
- Job queue — dispatches BirdNET inference jobs to workers via Redis + BullMQ
- Web UI — serves the React SPA via nginx, proxying
/api/*to the hub process - Database — PostgreSQL 17 with multi-tenant row-level isolation
- Storage — MinIO for S3-compatible audio and image blob storage
Docker Compose Deployment
Docker Compose is the primary and recommended deployment method.
Containers
| Container | Image | Purpose |
|---|---|---|
| postgres | PostgreSQL 17 | Multi-tenant data store |
| redis | Redis 7 | BullMQ job queue backend |
| mosquitto | Mosquitto 2.x | MQTT broker (dynamic security plugin) |
| minio | MinIO | S3-compatible audio + image storage |
| hub | Node.js | API gateway, MQTT ingester, background workers |
| web | nginx | React SPA, proxies /api/* to hub |
| docs | Node.js | Documentation site (Express + markdown-it) |
| worker | Python 3.11 | BirdNET inference (scalable) |
Networks
- traefik (external) — Traefik routes HTTPS/MQTTS/WSS traffic
- backend (internal) — Inter-container communication
Storage
All persistent data uses bind mounts under BNG_VOLUMES_ROOT (default: ./storage/):
storage/
├── postgres/ # Database files
├── redis/ # Redis AOF
├── mosquitto/ # Broker data + dynamic security DB
└── minio/ # Audio blobs + species images
Commands
# Start full stack
docker compose up -d
# Rebuild after code changes
docker compose up -d --build
# View logs
docker compose logs -f hub
# Stop everything
docker compose down
Configuration
All runtime configuration is via .env (see .env.example for the full template). No hardcoded secrets.
FQDNs
Four FQDNs are required, each configured in .env:
| Variable | Purpose |
|---|---|
BNG_APP_FQDN |
Web UI + API (HTTPS, nginx -> hub) |
BNG_MQTT_FQDN |
Mosquitto broker (MQTTS, Traefik TCP router, port 8883) |
BNG_S3_FQDN |
MinIO console (HTTPS) |
BNG_DOCS_FQDN |
Documentation site (HTTPS) |
Key Environment Variables
| Variable | Description |
|---|---|
JWT_SECRET |
Secret for signing JWT session tokens (required) |
PLATFORM_ADMIN_EMAILS |
Comma-separated email addresses that get platform admin access |
HUB_INTERNAL_API_KEY |
Backwards-compatible machine access key (optional) |
Traefik Configuration
Four routes are needed across two entrypoints:
| Entrypoint | Port | Protocol | Service |
|---|---|---|---|
| websecure | 443 | HTTPS | Web UI + API (BNG_APP_FQDN) |
| mqtts | 8883 | TCP (TLS) | MQTT broker (BNG_MQTT_FQDN) |
| websecure | 443 | HTTPS | MinIO console (BNG_S3_FQDN) |
| websecure | 443 | HTTPS | Documentation site (BNG_DOCS_FQDN) |
The docker-compose.yml includes Traefik labels for automatic routing. No services expose ports directly to the host; everything goes through Traefik.
Database Migrations
Migrations run automatically on hub startup (see packages/hub/src/db/migrate.ts). There are currently 13 migrations (001-013).
To run migrations manually:
docker compose exec hub node packages/hub/dist/db/migrate.js
Scaling Workers
Workers are stateless and can be scaled independently of the hub:
docker compose up --scale worker=4 -d
See the Workers page for detailed worker deployment options.