Getting Started
Otavi is a distributed bird sound identification system. Satellite nodes (Raspberry Pi or Android phones) capture audio and send it to a central hub that runs BirdNET inference and serves results through a web UI.
Prerequisites
- Docker + Docker Compose
- A domain name with DNS (4 subdomains needed)
- Traefik reverse proxy (or adapt for nginx/caddy)
- Node.js 24+ and pnpm (for development)
Quick Start
1. Clone and configure
# Clone the repository (replace with your Git server URL)
git clone <your-git-server>/birdnet-ng.git
cd birdnet-ng
cp .env.example .env
Note: If the repository is hosted on a private Git server (Gitea, GitLab, etc.), make sure you have access configured (SSH key or HTTPS credentials). For SSH:
git clone git@your-server:org/birdnet-ng.git
Edit .env with your settings:
# Required: your public names, and the Traefik resolver for their certificates
OTAVI_APP_FQDN=birdnet.example.com
OTAVI_MQTT_FQDN=mqtt.birdnet.example.com
OTAVI_DOCS_FQDN=docs.birdnet.example.com
OTAVI_TLS_CERTRESOLVER=letsencrypt
Then give every secret a random value. The hub refuses to start while any of them is still a placeholder from the example file or too short, and its log names the ones to fix:
for k in OTAVI_AUTH_JWT_SECRET OTAVI_AUTH_MFA_ENCRYPTION_KEY OTAVI_DB_PASSWORD OTAVI_S3_ROOT_PASSWORD \
OTAVI_MQTT_ADMIN_PASSWORD OTAVI_MQTT_HUB_PASSWORD OTAVI_HUB_INTERNAL_API_KEY; do
sed -i "s|^#\{0,1\} *$k=.*|$k=$(openssl rand -hex 32)|" .env
done
Set OTAVI_AUTH_PLATFORM_ADMIN_EMAILS to your address and create that account right after the first start: a listed address with no account yet goes to whoever registers it first, and the hub warns about it at every start until it exists.
2. Start the stack
docker compose up -d
This starts 8+ containers: PostgreSQL, Redis, Mosquitto, MinIO, Hub API, Web UI, Documentation site, and an inference worker (9 with split mode which adds a dispatcher).
3. Create your account
Open https://birdnet.example.com in your browser. Register an account, then create a tenant (team).
4. Deploy a satellite
See Satellite: Raspberry Pi or Satellite: Android guides.
Project Structure
birdnet-ng/
├── packages/
│ ├── shared/ — TypeScript types, constants, MQTT protocol
│ ├── satellite/ — Node.js agent for Raspberry Pi
│ ├── hub/ — Fastify API gateway, MQTT ingester, job queue
│ ├── inference/ — Python BirdNET inference worker
│ ├── mobile/ — Android phone satellite (Capacitor)
│ └── web/ — React SPA (Vite)
├── docs/ — This documentation site (Express + markdown-it)
├── config/ — Mosquitto configuration
├── docker-compose.yml
└── .env.example
Development
pnpm install
pnpm build # Build all TypeScript packages
pnpm dev # Run all packages in dev mode
pnpm docs:dev # Start documentation site locally