ncclient
ncclient is the preferred way to run Nebula Commander on devices: enroll once with a code from the UI, then ncclient polls for config and certificates and can run or restart Nebula when config changes. When you run the first lighthouse using the Docker client, you can use Magic DNS (split-horizon DNS) for the network.
- Installation – Docker (preferred for first lighthouse), binaries (Web UI or GitHub Releases), Windows Tray (MSI), or Pip (PyPI) as fallback.
- Usage – Command line (enrollment, daemon, service) and Windows Tray.
Both the CLI and the Windows tray assume the Nebula Commander backend is running and reachable at the URL you configure.
1 - ncclient Installation
You can install ncclient in several ways: Docker (preferred for the first lighthouse to use Magic DNS), binaries (Web UI or GitHub Releases), Windows MSI (CLI and tray app), or Pip (PyPI) as a fallback when Docker or binaries are not suitable.
Docker
The Docker client is the preferred method for the first lighthouse in a network so the container can run dnsmasq and you can use Magic DNS (split-horizon DNS) for the network. Other devices (CLI, tray, or additional Docker clients) can then resolve Nebula hostnames via the lighthouse.
Image: ghcr.io/nixrtr/nebula-commander-ncclient:latest, or build from the repo client/docker (Dockerfile in that directory).
Required environment:
NEBULA_COMMANDER_SERVER – Base URL of your Nebula Commander backend (e.g. https://nc.example.com), no trailing slash.
Optional environment:
ENROLL_CODE – One-time enrollment code from the Nebula Commander UI (Nodes → Enroll for the node). Only used when the token file does not exist; after enrollment the token is stored and this is ignored.SERVE_DNS – Set to "true" to run dnsmasq on this node when it is a lighthouse, so the network can use Magic DNS. Omit or set to false if this node is not a lighthouse or you do not need DNS.NEBULA_DNS_POLL_INTERVAL – Seconds between dnsmasq config polls when this node is a lighthouse (default: 60).NEBULA_OUTPUT_DIR – Directory where ncclient writes Nebula config and certs inside the container (default: /data/nebula).NEBULA_DEVICE_TOKEN_FILE – Path to the device token file (default: /data/nebula-commander/token).
Use a persistent volume for /data so the token and Nebula config/certs survive restarts. The compose file uses network_mode: host so Nebula and dnsmasq can bind to the host.
Example (docker-compose):
services:
ncclient:
image: ghcr.io/nixrtr/nebula-commander-ncclient:latest
network_mode: host
restart: unless-stopped
environment:
NEBULA_COMMANDER_SERVER: "https://nc.example.com"
ENROLL_CODE: "XXXXXXXX" # one-time, from UI
SERVE_DNS: "true" # for first lighthouse + Magic DNS
volumes:
- ncclient-data:/data
volumes:
ncclient-data:
driver: local
Steps:
- In Nebula Commander, create a network and add a node for this device. Mark it as a lighthouse if this will be the first lighthouse and you want Magic DNS.
- Create or sign a certificate for the node, then click Enroll and copy the one-time code.
- Set
NEBULA_COMMANDER_SERVER and ENROLL_CODE (and SERVE_DNS: "true" for the first lighthouse), then start the container. - After enrollment, the container fetches config and certs and runs Nebula (and dnsmasq if
SERVE_DNS is set and the node is a lighthouse).
Binaries
If Docker is not an option, use binaries from the Web UI or GitHub Releases.
From Web UI
When your Nebula Commander instance is deployed with client binaries included (for example the frontend image built with DOWNLOAD_BINARIES=1), the Web UI can serve them.
- Open your Nebula Commander URL in a browser and log in.
- Go to the downloads or client section (or open
https://YOUR_SERVER/downloads/ if your instance serves that path). - Download the binary for your platform:
- Linux x86_64:
ncclient-linux-amd64 - Linux ARM64:
ncclient-linux-arm64 - Windows x86_64:
ncclient-windows-amd64.exe - macOS Intel:
ncclient-macos-amd64 - macOS Apple Silicon:
ncclient-macos-arm64
- Place the file in a directory on your PATH (or add that directory to PATH). On Linux and macOS, make it executable:
chmod +x ncclient-linux-amd64 (or the file you downloaded).
If your instance does not serve binaries, use From releases or Pip (PyPI) instead.
From releases
Pre-built binaries are attached to GitHub Releases for each version.
- Open the releases page and choose a version (e.g. the latest).
- Download the file for your platform (same names as in From Web UI).
- Optionally verify with
SHA256SUMS.txt in the same release. - Place the binary in a directory on your PATH (or add that directory to PATH). On Linux and macOS, make it executable:
chmod +x ncclient-linux-amd64 (or the file you downloaded).
Windows Installer
On Windows you can install both the ncclient CLI and the optional tray app using the MSI installer.
What the installer includes:
- ncclient – CLI for enrollment and daemon (poll for config/certs, run or restart Nebula).
- ncclient-tray – System tray app: enroll, settings, start/stop polling, optional bundled Nebula, start at login.
Both are installed to %ProgramFiles%\Nebula Commander\. The installer can add that directory to PATH and create Start Menu shortcuts.
Getting the installer:
- Download
NebulaCommander-windows-amd64.msi from the GitHub Releases page for the version you want. - Use
SHA256SUMS.txt in the same release to verify the file.
After install:
- Enroll: in Nebula Commander go to Nodes, open the node, click Enroll, and copy the code. Then run:
ncclient enroll --server https://YOUR_SERVER_URL --code XXXXXXXX
- Run the client from the command line or use the tray app from the Start Menu (see Windows Tray in Usage).
For building the MSI yourself, see Development: Manual builds.
Pip (PyPI)
Fallback method when Docker or binaries are not suitable (e.g. no Docker, or you need to run from source).
From PyPI:
pip install nebula-commander
Requires Python 3.10+. This installs the ncclient command.
From source (repo clone):
cd nebula-commander
pip install -r client/requirements.txt
Then run as python -m client --server URL enroll --code XXX, or install the client in development mode to get the ncclient command:
cd client
pip install -e .
2 - ncclient Usage
After installing ncclient, enroll the device once, then run the daemon (or install the service on Linux).
Command Line
Enrollment
Enrollment is one-time per device. It stores a device token that ncclient uses to fetch config and certificates.
- In Nebula Commander, open Nodes, select the node for this device, and click Enroll.
- Copy the enrollment code.
- On the device, run:
ncclient enroll --server https://YOUR_NEBULA_COMMANDER_URL --code XXXXXXXX
The device token is saved to ~/.config/nebula-commander/token (or /etc/nebula-commander/token when run as root). On Windows, the token is stored under %USERPROFILE%\.config\nebula-commander\token.
Run (daemon)
After enrollment, run ncclient so it periodically pulls config and certificates and optionally runs or restarts Nebula:
ncclient run --server https://YOUR_NEBULA_COMMANDER_URL
Defaults: poll every 60 seconds, write files to /etc/nebula (or ~/.nebula on Windows), and start or restart Nebula from PATH when config changes.
Options
| Option | Description |
|---|
--output-dir DIR | Where to write config.yaml, ca.crt, host.crt (default: /etc/nebula on Linux/macOS, ~/.nebula on Windows) |
--interval N | Poll interval in seconds (default: 60) |
--token-file PATH | Path to device token file |
--nebula PATH | Path to the nebula binary if it is not on PATH |
--restart-service NAME | Instead of running nebula directly, restart this systemd service (e.g. nebula). Use only one of --nebula or --restart-service. |
--accept-dns | Enable split-horizon DNS: fetch DNS config from the server and apply it so the Nebula domain is resolved via the network’s DNS (lighthouses). On Linux use systemd-resolved, dnsmasq, or similar (run as root); on Windows uses NRPT (run as Administrator). See Split-horizon DNS below. |
Example with nebula in a non-standard location:
ncclient run --server https://nc.example.com --nebula /usr/local/bin/nebula
Example using systemd to run Nebula (ncclient only restarts the service):
ncclient run --server https://nc.example.com --restart-service nebula
Linux: Creating the Nebula TUN device requires root. Run ncclient as root, e.g. sudo ncclient run --server https://....
Split-horizon DNS
When the server has DNS enabled for the network, you can pass --accept-dns so ncclient fetches the DNS config (domain and lighthouse IPs) and configures the host to resolve the Nebula domain via the network’s DNS. On Linux the client tries, in order: systemd-resolved, dnsmasq, NetworkManager, systemd-networkd, then /etc/resolv.conf (best-effort). On Windows it uses NRPT. Run as root (Linux) or Administrator (Windows) to apply. To remove the DNS override on exit, stop ncclient normally (e.g. Ctrl+C); the client clears the rules on exit.
Certificates: If the cert was created via the server (Create certificate in the UI), the bundle includes host.key. If it was signed (Sign flow), the server does not have the key; put your host.key in the same directory as the generated certs (the output dir).
Install service
Linux (quick install)
On Linux you can install a systemd service with one command:
This checks for an existing token at /etc/nebula-commander/token. If missing, it prints the exact ncclient enroll ... command to run first. It then prompts for server URL and options (output dir, interval, nebula path, restart-service), writes /etc/default/ncclient and /etc/systemd/system/ncclient.service, and enables (and optionally starts) the service.
- Use
--no-start to enable without starting. - Use
--non-interactive with NEBULA_COMMANDER_SERVER (and optional env vars) set for scripting.
Run ncclient run under your init system (launchd on macOS, Task Scheduler or NSSM on Windows). Example configs are in the repo under examples/; see examples/README-startup.md for step-by-step setup on macOS and Windows.
Troubleshooting
- No TUN device / cannot ping Nebula IP – On Linux, run with
sudo. For Sign flow, ensure host.key is in the output directory. Check Nebula’s error output (e.g. “failed to get tun device”, “no such file”). - Nebula starts then exits – Often missing
host.key (Sign flow), wrong config path, or on Linux needing root. Check the Nebula lines ncclient prints.
macOS notes
Token: ~/.config/nebula-commander/token (or /etc/nebula-commander/token as root). Default output dir: /etc/nebula; for non-root use --output-dir ~/.nebula. Nebula: use PATH or --nebula /opt/homebrew/bin/nebula (Apple Silicon) or /usr/local/bin/nebula (Intel). Do not use --restart-service; use launchd for background runs.
Windows notes (CLI)
Token: %USERPROFILE%\.config\nebula-commander\token. Default output dir: %USERPROFILE%\.nebula. Use --nebula if nebula.exe is not on PATH. Do not use --restart-service. For a GUI and start at login, use the Windows Tray section below.
Windows Tray
The Windows tray app provides the same enroll-and-poll flow as the ncclient CLI but with a GUI: tray icon, Enroll and Settings dialogs, Start/Stop polling, optional bundled Nebula, and Start at login (Registry Run).
Usage
- Enroll – Open the tray menu and use Enroll. Enter the server URL and the one-time code from Nebula Commander (Nodes → Enroll for the node). The token is stored in the same location as the CLI (
%USERPROFILE%\.config\nebula-commander\token). - Settings – Configure server URL, output directory for config and certs, poll interval, optional path to the Nebula binary, and Accept split-horizon DNS (when the server has DNS enabled for the network, the tray can apply DNS so the Nebula domain is resolved via the network’s DNS; requires Administrator on Windows). When the app is built with bundled Nebula, the default Nebula path points to the bundled
nebula.exe. - Start / Stop polling – Start polling to fetch config and certs periodically and optionally run Nebula. Stop to pause.
- Start at login – When enabled, the app is registered in the Windows Registry (
HKCU\...\Run) so it starts when you sign in. No Windows Service is installed; the tray runs as a normal app.
Settings are stored in %APPDATA%\nebula-commander\settings.json.
Run from source
From the nebula-commander repo root:
pip install -r client/windows/requirements.txt
pip install -e client/
python -m client.windows.tray
Or with pythonw to avoid a console window:
pythonw -m client.windows.tray
Build (PyInstaller)
To build a standalone ncclient-tray.exe (and optionally bundle the Nebula Windows binary):
cd client/windows
pip install -r requirements.txt pyinstaller
python build.py
Output is in client/windows/dist/ (e.g. ncclient-tray.exe). See client/windows/README.md and build.py for details.
The Windows Tray installer (MSI) includes both the CLI and the tray app.