Getting Started

Installation

obserae is a self-contained Network Detection & Response (NDR) daemon plus a small admin CLI. This page covers the two supported install paths (Docker and pre-built binaries), plus the basics of pointing your NetFlow exporters at it.


System requirements

ResourceRecommended
OS / CPULinux, amd64 or arm64 (incl. Raspberry Pi 4/5 and ARM servers)
Memory1GB minimum, 2 GB+ for production
DiskSized for your retention and traffic volume. Start with a roomy data volume and tune retention once you know daily growth.
CPU load1 core is enough for most homelabs; 2–4 cores for production
NetworkUDP ports for NetFlow (default 2055) and IPFIX (default 4739), TCP port for the GUI (default 8080)

obserae runs entirely on disk — no Elasticsearch, no Kafka, no Redis. The only external dependency at runtime is the IP-enrichment HTTPS fetcher (AWS / Azure / GCP), and it can be disabled.


The image is published to GitHub Container Registry as a multi-arch manifest: Docker automatically pulls the amd64 or arm64 build to match your CPU, so the same command works on a server, a desktop, or a Raspberry Pi.

docker run -d \
  --name obserae \
  --restart unless-stopped \
  -p 2055:2055/udp \
  -p 4739:4739/udp \
  -p 127.0.0.1:8080:8080/tcp \
  -v obserae-data:/var/lib/obserae \
  ghcr.io/spartan-conseil/obserae:latest

What that does:

  • Forwards UDP 2055 (NetFlow ingest), UDP 4739 (IPFIX ingest) and TCP 8080 (web GUI, localhost) from the host to the container.
  • Mounts a named volume at /var/lib/obserae so traffic history, configuration, secrets and backups survive container restarts.
  • Loads the image’s default obserae.yaml, pre-configured for container paths.

Open http://localhost:8080 to reach the web GUI.

The login keeps bouncing back to the login page (remote / plain HTTP)? This is the single most common Docker gotcha. The container binds the GUI on all interfaces, so the session cookie is marked Secure by default — and a browser silently drops a Secure cookie received over plain http:// from a remote IP. So your password is accepted but the session never sticks and you loop. (It works from http://localhost:8080 only because browsers treat localhost as a secure context.) Two fixes:

  • Recommended — put TLS in front. Front obserae with a reverse proxy (Caddy, nginx, Traefik) terminating HTTPS and forwarding X-Forwarded-Proto: https. The cookie stays Secure and login works.
  • Plain-HTTP LAN deployment (no TLS, trusted network): mount a config with web.secure_cookies: false. The login then works over plain HTTP, but the session cookie travels unprotected — only do this on a trusted network. See Configuration.

Run as a non-root host user

By default the container runs as a built-in non-root user (UID 65532). To make the files in the data volume owned by your host user instead, run with --user and bind-mount a directory you own:

mkdir -p ./obserae-data
docker run -d \
  --name obserae \
  --restart unless-stopped \
  --user "$(id -u):$(id -g)" \
  -p 2055:2055/udp \
  -p 4739:4739/udp \
  -p 127.0.0.1:8080:8080/tcp \
  -v "$(pwd)/obserae-data:/var/lib/obserae" \
  ghcr.io/spartan-conseil/obserae:latest

Override the config

docker run -d \
  --name obserae \
  -p 2055:2055/udp \
  -p 4739:4739/udp \
  -p 127.0.0.1:8080:8080/tcp \
  -v "$(pwd)/obserae.yaml:/etc/obserae/obserae.yaml:ro" \
  -v obserae-data:/var/lib/obserae \
  ghcr.io/spartan-conseil/obserae:latest \
  --config /etc/obserae/obserae.yaml

For anything beyond http://localhost, run obserae behind a TLS reverse proxy so the GUI login works (see the login-loop note above). A turnkey obserae + Caddy stack ships in the docker-compose/ directory — it brings up HTTPS on :443 with a self-signed certificate, no domain or DNS required:

cd docker-compose
docker compose up -d

# first-boot admin password (printed once)
docker compose logs obserae | grep "generated admin password"

Open https://ip and click through the one-time “not trusted” warning (self-signed CA). Caddy terminates TLS and forwards X-Forwarded-Proto: https, so obserae keeps the session cookie Secure and the login sticks.

What the stack runs:

  • obserae — publishes only the flow-ingest ports (2055/udp, 4739/udp) to the host; the GUI (8080) is reachable only through Caddy, never as plain HTTP.
  • caddy — serves the GUI over HTTPS on :443 (and :80, used only when you switch to a real domain).

Real domain + browser-trusted certificate. Edit the bundled Caddyfile: swap the self-signed block for the commented production block (your domain → reverse_proxy obserae:8080), point the domain’s DNS at this host, and make ports 80 and 443 reachable from the internet. Caddy then provisions and auto-renews a Let’s Encrypt certificate — no more warnings.

Run the admin CLI against the container

docker exec -it obserae obserae-cli status

Option 2 — Pre-built binaries

Download the tarball for your architecture. The URLs below always resolve to the newest release.

# amd64 — most servers, desktops, mini-PCs
curl -L -o obserae.tar.gz \
  https://github.com/spartan-conseil/obserae/releases/latest/download/obserae_linux_amd64.tar.gz

# arm64 — Raspberry Pi 4/5, ARM servers
curl -L -o obserae.tar.gz \
  https://github.com/spartan-conseil/obserae/releases/latest/download/obserae_linux_arm64.tar.gz

Which architecture? Run uname -m: x86_64 → amd64, aarch64 → arm64.

Extract and run:

tar xzf obserae.tar.gz
cd obserae_linux_*

mkdir -p data
./obserae --config obserae.yaml

What’s inside the tarball:

obserae_linux_<arch>/
├── obserae               # daemon (collects NetFlow/IPFIX and serves the GUI)
├── obserae-cli           # admin CLI
├── obserae.yaml          # minimal config (edit before production use)
├── EULA.txt              # license / terms of use
└── docs/                 # the full user documentation

The daemon prints INFO control api listening and INFO collector listening once it is ready. Open http://localhost:8080 to reach the web GUI. To stop, press Ctrl+C.

For a long-running install, see Operations for the systemd unit.

Verify before you run. The release is keyless-signed and ships an SBOM and provenance attestation. To check the tarball’s integrity, signature and origin, see Verify a Release.


After installing — send flows to obserae

obserae listens on UDP 2055 (NetFlow v5/v9) and UDP 4739 (IPFIX). Point each device or software probe at <obserae-host> on the matching port.

Per-device setup for Cisco, Juniper, MikroTik, FortiGate, Palo Alto, pfSense/OPNsense, Open vSwitch, host probes and many more — and how to confirm flows are arriving — has its own page: Configuring Exporters.


Next steps