Skip to content

Installation

Northplane is one static binary (northplaned) plus the np CLI and the np-agent host agent. Pick the variant that matches how you run services; they all produce the same server with the same data layout, so you can start with one and move to another later.

Variant Best for TLS You get
Release tarball (+ northplaned init, systemd) VMs and bare metal, Linux/macOS your certificate pair, or a reverse proxy with trustProxy northplaned, np, np-agent in /usr/local/bin
Docker image container hosts, Kubernetes, quick trials your certificate pair, a proxy, or NORTHPLANE_TLS_INSECURE=true locally northplaned + np in a distroless image (no np-agent)
Docker Compose with bundled Caddy a single box that should just have HTTPS automatic (Let’s Encrypt or an internal CA) Northplane + Caddy, optional PostgreSQL
Build from source development, unreleased versions, other platforms as above bin/northplaned, bin/np, bin/np-agent, bin/np-gen

Releases live on GitHub, the container image on GHCR (ghcr.io/myfoxit/northplane); both are public — no login, no token.

Releases are tagged v*. Each release carries:

Asset Contents
northplane_<tag>_linux_amd64.tar.gz, northplane_<tag>_linux_arm64.tar.gz northplaned, np, np-agent, LICENSE
northplane_<tag>_darwin_amd64.tar.gz, northplane_<tag>_darwin_arm64.tar.gz northplaned, np, np-agent, LICENSE
northplane_<tag>_windows_amd64.zip np.exe, np-agent.exe, LICENSEno northplaned (it needs Unix process groups for plugin execution)
checksums.txt sha256sum lines for every asset

The asset name keeps the leading v of the tag (northplane_v1.2.0_linux_amd64.tar.gz) while the version baked into the binaries strips it (northplaned versionnorthplaned 1.2.0). Binaries are static (CGO_ENABLED=0), so they run on any glibc or musl distribution.

The one-line installer resolves the newest release through the GitHub API, downloads the matching tarball and checksums.txt, verifies the SHA-256 and installs northplaned np np-agent:

Terminal window
curl -fsSL https://raw.githubusercontent.com/myfoxit/northplane/main/install.sh | sh

What it does, exactly:

  • Supports Linux and macOS on x86_64/amd64 and aarch64/arm64; needs curl, tar and sha256sum or shasum.
  • Installs into /usr/local/bin. If that is not writable it uses sudo (the password prompt comes from /dev/tty, so this also works in the curl … | sh form); without sudo it falls back to ~/.local/bin (created if missing, with a note if it is not on PATH).
  • Picks the newest release; if only pre-releases exist it takes the newest of those.
  • Is safe to re-run: existing binaries are replaced.
  • Writes no configuration and no service unit; it ends with the two next steps — northplaned serve for a loopback trial and sudo northplaned init + systemctl enable --now northplaned for a service.
Variable Effect
NP_VERSION=v1.2.3 install that release instead of the newest (1.2.3 is accepted too)
NP_INSTALL_DIR=/opt/bin install directory (no fallback to ~/.local/bin when set)
NP_BINARIES="np-agent" install a subset — what the Admin → Agents tab shows for monitored hosts

Manual equivalent (any release, any platform from the matrix):

Terminal window
tag=v1.2.0 os=linux arch=amd64
curl -fsSLO "https://github.com/myfoxit/northplane/releases/download/${tag}/northplane_${tag}_${os}_${arch}.tar.gz"
curl -fsSLO "https://github.com/myfoxit/northplane/releases/download/${tag}/checksums.txt"
grep " northplane_${tag}_${os}_${arch}.tar.gz\$" checksums.txt | sha256sum -c - # macOS: shasum -a 256 -c -
tar -xzf "northplane_${tag}_${os}_${arch}.tar.gz"
sudo install -m 0755 northplaned np np-agent /usr/local/bin/
northplaned version

A first trial needs no configuration: northplaned serve listens on 127.0.0.1:8443 (plain HTTP is allowed on loopback) and stores data under your user’s data directory. For a permanent install continue with Set up as a service.

northplaned init turns a bare binary into a permanent install. Run it as root on the target host:

Terminal window
sudo northplaned init # --dir /etc/northplane --data /var/lib/northplane --user northplane
sudo systemctl enable --now northplaned
Flag Default Meaning
--dir /etc/northplane as root; ~/.config/northplane (macOS: ~/Library/Application Support/northplane) otherwise configuration directory
--data /var/lib/northplane as root; ~/.local/share/northplane / $XDG_DATA_HOME/northplane (macOS: ~/Library/Application Support/northplane) otherwise data directory written into the config
--user northplane system account the service runs as (created when missing — root on Linux only)

It creates both directories (0750) and writes three files; it refuses to overwrite an existing config.yaml (<path> exists — refusing to overwrite):

File Mode Content
<dir>/config.yaml 0640 the commented bootstrap template: listen: "127.0.0.1:8443", dataDir, secretKeyFile, empty storage.dsn (= SQLite), empty tls, commented oidc/ldap/federation blocks, ai.provider: none, backup.target: "". Shown verbatim in Configuration.
<dir>/secret.key 0600 32 random bytes as 64 hex characters — the AES-256-GCM master key for secrets at rest. Back it up.
northplaned.service 0644 the systemd unit below — written straight to /etc/systemd/system/ when init runs as root on a Linux host with systemd, otherwise next to the config for manual use

As root on Linux, init additionally creates the locked system user (useradd --system --no-create-home --shell nologin), hands it the configuration directory, config.yaml, secret.key and the data directory, and installs the unit — so the printed next step is literally systemctl enable --now northplaned. On other systems (or without useradd) it prints what is left to do by hand.

/etc/systemd/system/northplaned.service (generated)
[Unit]
Description=Northplane monitoring server
Documentation=https://github.com/myfoxit/northplane
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/northplaned serve -config /etc/northplane/config.yaml
Restart=on-failure
RestartSec=2
User=northplane
Group=northplane
StateDirectory=northplane
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ReadWritePaths=/var/lib/northplane
[Install]
WantedBy=multi-user.target

ExecStart uses the path of the binary that ran init. There is deliberately no WatchdogSec: northplaned does not speak sd_notify, and a watchdog without keep-alives would restart the service every interval.

The command ends with:

next steps:
1. review /etc/northplane/config.yaml (listen/TLS, storage backend, OIDC)
2. systemctl enable --now northplaned
3. open http://127.0.0.1:8443/setup in the browser to create the admin account
(or headless: northplaned bootstrap-admin -config /etc/northplane/config.yaml)

A complete first start on a systemd host:

  1. Install the binaries (installer, tarball or source build) and run sudo northplaned init.

  2. Review /etc/northplane/config.yaml. To serve the network set listen: ":8443" and either tls.certFile/tls.keyFile or trustProxy: true behind a TLS-terminating proxy; the loopback default exists so that plaintext is never exposed by accident. Set baseUrl to the public URL (used in notification links, ack links and OIDC redirects). Keys and defaults: Configuration, TLS options: TLS and proxy.

  3. Start it and watch the log:

    Terminal window
    sudo systemctl enable --now northplaned
    journalctl -u northplaned -f

    Environment variables such as NP_DEFAULT_ADMIN_DISABLED=1 or NP_DEFAULT_ADMIN_PASSWORD=… go into a drop-in (sudo systemctl edit northplaned[Service] / Environment=…).

  4. Create the admin: open /setup (only open while no local user and no API token exist and the default-admin seeding is disabled — see Quickstart), or run sudo -u northplane northplaned bootstrap-admin -config /etc/northplane/config.yaml for a headless *:* token.

If secret.key is not readable by the service user (for example after moving files by hand), the server warns configured secretKeyFile unusable — falling back to the data directory and generates a second key under /var/lib/northplane/secret.key — workable, but then the key in /etc/northplane is not the one in use. No SIGHUP reload exists: configuration changes need systemctl restart northplaned. Shutdown is graceful (SIGTERM, 30 s budget for in-flight requests and workers).

Prerequisites: Go 1.25 and Node.js 22 (npm). The Go build is CGO-free (pure-Go SQLite), so no C toolchain is needed.

Terminal window
git clone https://github.com/myfoxit/northplane.git && cd northplane
make all # = make web (UI) + make docs (this manual) + make build
./bin/northplaned version
Target What it does
make web npm ci + Vite build in web/, copies web/dist to internal/web/dist (embedded via go:embed)
make docs npm ci + Astro/Starlight build in docs/ (fails on broken links), stages docs/dist into internal/docs/dist
make build go build -ldflags "-X main.version=$(VERSION)"bin/northplaned, bin/np, bin/np-agent, bin/np-gen; VERSION defaults to 1.0.0-dev
make docker builds the container image northplane:$(VERSION)
make test / make race go vet + go test (CI runs the race detector)
make dev hot-reload development loop: Vite on :5173, auto-rebuilt backend on 127.0.0.1:8443, demo data seeded (NP_DEV_DEMO=0 to skip)

A plain go build ./cmd/northplaned also works, but it embeds whatever internal/web/dist is committed (which may be stale) and no documentation — /docs/ then answers 501 documentation not embedded in this build — run make docs. Release-style static cross builds:

Terminal window
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -trimpath \
-ldflags "-s -w -X main.version=1.2.0" -o northplaned ./cmd/northplaned

Cross-compiling northplaned for Windows is not supported (CI skips it); np and np-agent build for windows/amd64. The development workflow (worktrees, lint, tests, e2e) is described in Development setup.

Linux amd64 / arm64 macOS amd64 / arm64 Windows amd64
northplaned yes — tarball, container image, source yes — tarball, source no (not built: plugin execution needs Unix process groups)
np yes yes yes (np.exe in the release zip)
np-agent yes — load, memory, disk, processes, network, plugins yes — same as Linux yes (np-agent.exe) — memory, disk, CPU, processes, plugins; no load or network collectors; runs as a console process under sc.exe
install.sh yes yes no — use the release zip
Service manager systemd unit from northplaned init; agent unit snippet in Admin → Agents launchd plist snippet for the agent in Admin → Agents sc.exe create snippet for the agent
Container linux/amd64, linux/arm64 via Docker Desktop (Linux image) via Docker Desktop (Linux image)

builtin:icmp uses unprivileged datagram ICMP first and falls back to a raw socket; on Linux without root or cap_net_raw it reports UNKNOWN - icmp socket: …. Nagios plugins for exec: checks are looked up under pluginsDir, auto-detected from /usr/lib/nagios/plugins, /usr/lib64/nagios/plugins, /usr/local/libexec/nagios, /opt/homebrew/libexec, then <dataDir>/plugins.

SQLite (default, storage.dsn: "") is the fully supported and CI-green backend and needs nothing else. PostgreSQL is selected by a DSN:

config.yaml
storage:
dsn: "postgres://np:secret@db:5432/northplane?sslmode=require"
eventRetentionMonths: 12

or NORTHPLANE_STORAGE_DSN=postgres://…. Facts to know before you choose it:

  • Driver pgx; schema migrations run automatically on every start (also by northplaned migrate). Pool: 16 open / 8 idle connections. Events are stored in monthly partitions; the janitor enforces eventRetentionMonths nightly.
  • The NP-TSDB stays on local disk under <dataDir>/tsdb regardless of the relational backend — the data directory (and its secret.key) is still required and still needs backups.
  • northplaned backup does not dump PostgreSQL; the manifest records the schema version and a note that relational backup is the operator’s job (pg_dump/PITR). The TSDB is still copied.
  • Known caveat: the audit-log chain verification (POST /api/v1/audit:verify, np audit verify) fails on PostgreSQL because jsonb normalises the stored JSON that the row hash was computed over. The CI job for PostgreSQL is non-blocking for this reason.
  • Moving an existing SQLite install: stop the server, run northplaned storage migrate --to "postgres://…" -config /etc/northplane/config.yaml, point storage.dsn at the target, start again (offline copy; the TSDB is untouched).

The Compose file has a commented postgres:16 service ready to uncomment. Details, table layout and sizing: Storage.

What Location
Config file -config <path>; default /etc/northplane/config.yaml as root; for other users /etc/northplane/config.yaml if it exists, else ~/.config/northplane/config.yaml (Linux) / ~/Library/Application Support/northplane/config.yaml (macOS). A missing file is fine — defaults and NORTHPLANE_* variables apply.
Data directory (dataDir) /var/lib/northplane as root; $XDG_DATA_HOME/northplane or ~/.local/share/northplane (Linux); ~/Library/Application Support/northplane (macOS); /var/lib/northplane in the container. Holds core.db (+ -wal/-shm), events-YYYYMM.db segments, tsdb/, artifacts/, optionally plugins/ and the fallback secret.key.
Secret key secretKeyFile from the config (northplaned init writes <config dir>/secret.key); fallback <dataDir>/secret.key, generated on first start.
Binaries /usr/local/bin/{northplaned,np,np-agent} (tarball/installer), bin/ (source build), /usr/local/bin/{northplaned,np} in the image.
Agent config /etc/northplane/agent.yaml (root or if it exists), else ~/.config/northplane/agent.yaml; Windows C:\ProgramData\northplane\agent.yaml — see Agent.

Upgrades are in-place: replace the binary (or pull the new image tag) and restart; pending schema migrations are applied automatically on start and the embedded UI and docs are always the matching version. Back up secret.key and the data directory (or run northplaned backup) first, and read Upgrades for rollback notes per variant.

There is no uninstall script. Remove what the variant created:

Terminal window
# systemd install
sudo systemctl disable --now northplaned
sudo rm /etc/systemd/system/northplaned.service && sudo systemctl daemon-reload
sudo rm /usr/local/bin/northplaned /usr/local/bin/np /usr/local/bin/np-agent
sudo rm -r /etc/northplane /var/lib/northplane # config, secret.key, database, TSDB
sudo userdel northplane
# docker run
docker rm -f northplane && docker volume rm northplane-data
# docker compose (also removes the Caddy volumes)
docker compose down -v

Agents are removed on their hosts the same way (systemctl disable --now np-agent, /etc/northplane/agent.yaml, the binary); revoke their API tokens under Admin → API tokens.