<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Nebula Commander</title><link>https://nebulacommander.com/</link><description>Recent content on Nebula Commander</description><generator>Hugo</generator><language>en</language><lastBuildDate>Wed, 16 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://nebulacommander.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Docker</title><link>https://nebulacommander.com/docs/usage/ncclient/installation/docker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/ncclient/installation/docker/</guid><description>&lt;p&gt;The Docker client is the &lt;strong&gt;preferred&lt;/strong&gt; method for the &lt;strong&gt;first lighthouse&lt;/strong&gt; in a network so the container can run dnsmasq and you can use &lt;a href="https://nebulacommander.com/docs/web-ui/dns/"&gt;Magic DNS&lt;/a&gt; (split-horizon DNS) for the network. Other devices (CLI, a native GUI app, or additional Docker clients) can then resolve Nebula hostnames via the lighthouse.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Image:&lt;/strong&gt; &lt;code&gt;ghcr.io/nebula-commander/nebula-commander-ncclient:latest&lt;/code&gt;, or build from the repo &lt;code&gt;client/docker&lt;/code&gt; (Dockerfile in that directory).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Required environment:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;NEBULA_COMMANDER_SERVER&lt;/code&gt; – Base URL of your Nebula Commander backend (e.g. &lt;code&gt;https://nc.example.com&lt;/code&gt;), no trailing slash.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Optional environment:&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Docker</title><link>https://nebulacommander.com/docs/installation/docker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/installation/docker/</guid><description>&lt;p&gt;Run Nebula Commander with Docker using pre-built images or a local build. You can download all required files without cloning the repository. For HTTPS and HSTS at the edge (Nginx, Traefik, or Caddy in front of the frontend container), see &lt;a href="https://nebulacommander.com/docs/installation/reverse-proxy/"&gt;Reverse Proxy&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="downloading-files"&gt;Downloading files&lt;/h2&gt;
&lt;p&gt;You need: &lt;code&gt;docker-compose.yml&lt;/code&gt;, &lt;code&gt;docker-compose-keycloak.yml&lt;/code&gt;, &lt;code&gt;.env.example&lt;/code&gt;, and the &lt;code&gt;env.d.example/&lt;/code&gt; directory (backend and Keycloak config). Either use the commands below or the provided script.&lt;/p&gt;
&lt;h3 id="using-curl"&gt;Using curl&lt;/h3&gt;
&lt;p&gt;Run these in an empty directory (or where you want the Docker setup):&lt;/p&gt;</description></item><item><title>Environment Variables</title><link>https://nebulacommander.com/docs/configuration/environment/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/configuration/environment/</guid><description>&lt;p&gt;All backend settings use the &lt;code&gt;NEBULA_COMMANDER_&lt;/code&gt; prefix. Set them in the environment or in a file (e.g. &lt;code&gt;docker/env.d/backend&lt;/code&gt;). Optional values can be omitted; defaults apply.&lt;/p&gt;
&lt;h2 id="application"&gt;Application&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Variable&lt;/th&gt;
 &lt;th&gt;Description&lt;/th&gt;
 &lt;th&gt;Default&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;NEBULA_COMMANDER_DEBUG&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Enable debug mode (enables dev-token endpoint; do not use in production)&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;false&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;NEBULA_COMMANDER_API_DOCS_ENABLED&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;From v0.9.0. Serve the interactive API docs at &lt;code&gt;/api/docs&lt;/code&gt; (Swagger UI) and &lt;code&gt;/api/redoc&lt;/code&gt;, with the schema at &lt;code&gt;/api/openapi.json&lt;/code&gt;. Every API endpoint still requires authentication either way; set to &lt;code&gt;false&lt;/code&gt; to hide the endpoint list and the server version from anyone who can reach the server. NixOS: &lt;code&gt;services.nebula-commander.apiDocs&lt;/code&gt;.&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;NEBULA_COMMANDER_UPDATE_CHECK_ENABLED&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Check GitHub for a newer release, shown as a notification in the About screen. Set to &lt;code&gt;false&lt;/code&gt; to disable all outbound calls to github.com (air-gapped/privacy-conscious deployments).&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;true&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="database"&gt;Database&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Variable&lt;/th&gt;
 &lt;th&gt;Description&lt;/th&gt;
 &lt;th&gt;Default&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;NEBULA_COMMANDER_DATABASE_URL&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Database URL (SQLite: use four slashes for absolute path, e.g. &lt;code&gt;sqlite+aiosqlite:////var/lib/nebula-commander/db.sqlite&lt;/code&gt;)&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;sqlite+aiosqlite:////var/lib/nebula-commander/db.sqlite&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;NEBULA_COMMANDER_DATABASE_PATH&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Override for SQLite path&lt;/td&gt;
 &lt;td&gt;—&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;NEBULA_COMMANDER_CERT_STORE_PATH&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Directory for CA and host certificates&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;/var/lib/nebula-commander/certs&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="encryption-at-rest"&gt;Encryption at rest&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Required.&lt;/strong&gt; The backend refuses to boot if this is left at a placeholder/unset
value — unlike most settings here, there&amp;rsquo;s no insecure-but-working default.&lt;/p&gt;</description></item><item><title>ncclient CLI</title><link>https://nebulacommander.com/docs/usage/ncclient/usage/cli/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/ncclient/usage/cli/</guid><description>&lt;p&gt;This page covers the plain &lt;code&gt;ncclient&lt;/code&gt; command from the &lt;a href="https://nebulacommander.com/docs/usage/ncclient/installation/binaries/"&gt;binaries&lt;/a&gt; or &lt;a href="https://nebulacommander.com/docs/usage/ncclient/installation/pip/"&gt;Pip&lt;/a&gt;, run by hand or under your own init system. If you installed the Linux packages, the Windows MSI, or the NixOS module, use the &lt;a href="https://nebulacommander.com/docs/usage/ncclient/usage/linux/"&gt;Linux App&lt;/a&gt;, &lt;a href="https://nebulacommander.com/docs/usage/ncclient/usage/windows/"&gt;Windows App&lt;/a&gt;, or &lt;a href="https://nebulacommander.com/docs/usage/ncclient/usage/nixos/"&gt;NixOS&lt;/a&gt; page instead. Those set up a background service that keeps its state somewhere the plain CLI doesn&amp;rsquo;t look.&lt;/p&gt;
&lt;h2 id="where-state-lives"&gt;Where state lives&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;What&lt;/th&gt;
 &lt;th&gt;Default location&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Device tokens (one per network)&lt;/td&gt;
 &lt;td&gt;The OS keyring, when there is a usable one (normally only in a logged-in desktop session). Otherwise files in &lt;code&gt;~/.nebula/tokens/&lt;/code&gt;, readable only by their owner. That&amp;rsquo;s what root, servers, SSH sessions, and the frozen binaries get. Set &lt;code&gt;NEBULA_DEVICE_TOKEN_FILE&lt;/code&gt; to a file path, and the tokens go in a &lt;code&gt;tokens/&lt;/code&gt; folder next to it.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;settings.json&lt;/code&gt; (each network&amp;rsquo;s server, node ID, accepted routes)&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;~/.config/nebula-commander/&lt;/code&gt; on Linux and macOS, &lt;code&gt;%APPDATA%\nebula-commander\&lt;/code&gt; on Windows. Set &lt;code&gt;NEBULA_COMMANDER_CONFIG_DIR&lt;/code&gt; to change it.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Nebula config and certificates&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;networks/&amp;lt;id&amp;gt;/&lt;/code&gt; under the output directory: &lt;code&gt;/etc/nebula&lt;/code&gt; on Linux and macOS, &lt;code&gt;%USERPROFILE%\.nebula&lt;/code&gt; on Windows. Set with &lt;code&gt;--output-dir&lt;/code&gt;.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Before v0.8.0 there was one token (&lt;code&gt;~/.nebula/device-token&lt;/code&gt;) and the Nebula files were directly in the output directory. ncclient moves them into this layout the first time v0.8.0 or newer runs.&lt;/p&gt;</description></item><item><title>Networks</title><link>https://nebulacommander.com/docs/web-ui/networks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/web-ui/networks/</guid><description>&lt;p&gt;The &lt;strong&gt;Networks&lt;/strong&gt; page shows every Nebula network you can access as a grid of square
cards, and lets you create networks. Each network has a name and a subnet (CIDR)
used for IP allocation to nodes.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Light&lt;/th&gt;
 &lt;th&gt;Dark&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/networks.png" alt="Networks page"&gt;&lt;/td&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/dark/networks.png" alt="Networks page in dark mode"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Click a network&amp;rsquo;s card to open its detail view: node/user/group counts and the
&lt;strong&gt;Group Access Diagram&lt;/strong&gt;, a live visualization of which groups can reach which
(see &lt;a href="https://nebulacommander.com/docs/web-ui/groups/"&gt;Groups&lt;/a&gt; for what restricted vs. open means).&lt;/p&gt;</description></item><item><title>Development Setup</title><link>https://nebulacommander.com/docs/development/setup/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/development/setup/</guid><description>&lt;p&gt;Run the backend and frontend locally for development.&lt;/p&gt;
&lt;h2 id="backend"&gt;Backend&lt;/h2&gt;
&lt;p&gt;From the &lt;code&gt;nebula-commander&lt;/code&gt; repository root:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;python -m venv .venv
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;source .venv/bin/activate &lt;span style="color:#75715e"&gt;# or .venv\Scripts\activate on Windows&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pip install -r backend/requirements.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export NEBULA_COMMANDER_DATABASE_URL&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;sqlite+aiosqlite:///./backend/db.sqlite&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export NEBULA_COMMANDER_CERT_STORE_PATH&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;./backend/certs&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Required — the backend refuses to boot without it. Generate one:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# python -c &amp;#34;from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export NEBULA_COMMANDER_ENCRYPTION_KEY&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;your-fernet-key-here&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export NEBULA_COMMANDER_DEBUG&lt;span style="color:#f92672"&gt;=&lt;/span&gt;true
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;python -m uvicorn backend.main:app --reload --port &lt;span style="color:#ae81ff"&gt;8081&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Use a real JWT secret in production; for local dev, &lt;code&gt;NEBULA_COMMANDER_DEBUG=true&lt;/code&gt;
enables the dev-token endpoint. Every backend setting uses the
&lt;code&gt;NEBULA_COMMANDER_&lt;/code&gt; prefix — a bare &lt;code&gt;DEBUG=true&lt;/code&gt; without it is silently ignored.&lt;/p&gt;</description></item><item><title>Signing up</title><link>https://nebulacommander.com/docs/cloud/signing-up/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/cloud/signing-up/</guid><description>&lt;p&gt;Setting up takes a few minutes. Your instance is created automatically as soon as payment goes
through.&lt;/p&gt;
&lt;h2 id="1-choose-a-name-and-plan"&gt;1. Choose a name and plan&lt;/h2&gt;
&lt;p&gt;Go to &lt;a href="https://cloud.nebulacdr.net/signup"&gt;cloud.nebulacdr.net/signup&lt;/a&gt; and fill in:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Email:&lt;/strong&gt; this account becomes the administrator of your instance.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Organization or project name.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Subdomain:&lt;/strong&gt; your instance&amp;rsquo;s address, for example &lt;code&gt;acme&lt;/code&gt; for &lt;code&gt;acme.nebulacdr.net&lt;/code&gt;. Use 3–32
lowercase letters, digits and hyphens. The form tells you straight away if a name is taken or
reserved.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plan:&lt;/strong&gt; &lt;em&gt;Hosted&lt;/em&gt; at the standard price, or &lt;em&gt;Name your own price&lt;/em&gt;. For the second, enter your
monthly amount (at least the minimum shown) or pick one of the suggested amounts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Accept the Terms of Service, then click &lt;strong&gt;Continue to payment&lt;/strong&gt;. Your subdomain is held for you
while you complete checkout.&lt;/p&gt;</description></item><item><title>Binaries</title><link>https://nebulacommander.com/docs/usage/ncclient/installation/binaries/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/ncclient/installation/binaries/</guid><description>&lt;p&gt;If Docker is not an option, use binaries from the Web UI or GitHub Releases.&lt;/p&gt;
&lt;h2 id="from-web-ui"&gt;From Web UI&lt;/h2&gt;
&lt;p&gt;When your Nebula Commander instance is deployed with client binaries included (for example the frontend image built with &lt;code&gt;DOWNLOAD_BINARIES=1&lt;/code&gt;), the Web UI can serve them.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open your Nebula Commander URL in a browser and log in.&lt;/li&gt;
&lt;li&gt;Go to the downloads or client section (or open &lt;code&gt;https://YOUR_SERVER/downloads/&lt;/code&gt; if your instance serves that path).&lt;/li&gt;
&lt;li&gt;Download the binary for your platform:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Linux x86_64:&lt;/strong&gt; &lt;code&gt;ncclient-linux-amd64&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Linux ARM64:&lt;/strong&gt; &lt;code&gt;ncclient-linux-arm64&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Windows x86_64:&lt;/strong&gt; &lt;code&gt;ncclient-windows-amd64.exe&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;macOS Intel:&lt;/strong&gt; &lt;code&gt;ncclient-macos-amd64&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;macOS Apple Silicon:&lt;/strong&gt; &lt;code&gt;ncclient-macos-arm64&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Place the file in a directory on your PATH (or add that directory to PATH). On Linux and macOS, make it executable: &lt;code&gt;chmod +x ncclient-linux-amd64&lt;/code&gt; (or the file you downloaded).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If your instance does not serve binaries, use &lt;a href="https://nebulacommander.com/docs/usage/ncclient/installation/binaries/#from-releases"&gt;From releases&lt;/a&gt; or &lt;a href="https://nebulacommander.com/docs/usage/ncclient/installation/pip/"&gt;Pip (PyPI)&lt;/a&gt; instead.&lt;/p&gt;</description></item><item><title>Docker</title><link>https://nebulacommander.com/docs/usage/ncclient/usage/docker/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/ncclient/usage/docker/</guid><description>&lt;p&gt;The Docker client runs ncclient, Nebula, and (on lighthouses) dnsmasq in one container. See &lt;a href="https://nebulacommander.com/docs/usage/ncclient/installation/docker/"&gt;Docker installation&lt;/a&gt; for the image and a full &lt;code&gt;docker-compose.yml&lt;/code&gt;. The commands below assume that compose file, with the service named &lt;code&gt;ncclient&lt;/code&gt;, run from the directory that holds it.&lt;/p&gt;
&lt;h2 id="where-state-lives"&gt;Where state lives&lt;/h2&gt;
&lt;p&gt;Everything that must survive a container recreate lives in the &lt;code&gt;/data&lt;/code&gt; volume, as long as the compose file sets these two paths (the example does):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;NEBULA_OUTPUT_DIR&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;/data/nebula&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;NEBULA_DEVICE_TOKEN_FILE&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;/data/nebula-commander/token&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Path in the container&lt;/th&gt;
 &lt;th&gt;What it is&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/data/nebula-commander/tokens/&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Device token (from v0.8.0, one file per network, named by its id)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/data/nebula-commander/settings.json&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Server URL, node ID, accepted routes&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/data/nebula/networks/&amp;lt;id&amp;gt;/&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Nebula &lt;code&gt;config.yaml&lt;/code&gt;, certificates, status&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Before v0.8.0 the token was &lt;code&gt;/data/nebula-commander/token&lt;/code&gt; and the Nebula files were directly in &lt;code&gt;/data/nebula/&lt;/code&gt;. The container moves them into this layout on its first start with v0.8.0 or newer; the variables stay the same.&lt;/p&gt;</description></item><item><title>GitHub Actions</title><link>https://nebulacommander.com/docs/development/github-actions/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/development/github-actions/</guid><description>&lt;p&gt;Nebula Commander uses two GitHub Actions workflows: one to build ncclient binaries (and create releases), and one to build and push Docker images.&lt;/p&gt;
&lt;h2 id="build-ncclient-binaries"&gt;Build ncclient Binaries&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Workflow file:&lt;/strong&gt; &lt;code&gt;.github/workflows/build-ncclient-binaries.yml&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="triggers"&gt;Triggers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Version tags&lt;/strong&gt; – Push a tag matching &lt;code&gt;v*&lt;/code&gt; (e.g. &lt;code&gt;v0.1.5&lt;/code&gt;) to build all binaries and create a GitHub Release. This is the only trigger that produces a release; there is no trigger on push to &lt;code&gt;main&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pull requests&lt;/strong&gt; – Runs when changes touch &lt;code&gt;client/binaries/**&lt;/code&gt;, &lt;code&gt;client/windows/**&lt;/code&gt;, &lt;code&gt;client/ncclient.py&lt;/code&gt;, &lt;code&gt;installer/windows/**&lt;/code&gt;, or the workflow file itself.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Manual&lt;/strong&gt; – Use &amp;ldquo;Run workflow&amp;rdquo; in the Actions tab (&lt;code&gt;workflow_dispatch&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="platforms-built"&gt;Platforms built&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Platform&lt;/th&gt;
 &lt;th&gt;Artifact name&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Linux x86_64&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;ncclient-linux-amd64&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Linux ARM64&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;ncclient-linux-arm64&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Windows x86_64&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;ncclient-windows-amd64.exe&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;macOS Intel&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;ncclient-macos-amd64&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;macOS ARM64 (Apple Silicon)&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;ncclient-macos-arm64&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Windows ARM64 is not built (GitHub has no Windows ARM64 runners). Linux ARM64 is built in Docker with QEMU on the host runner.&lt;/p&gt;</description></item><item><title>Groups</title><link>https://nebulacommander.com/docs/web-ui/groups/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/web-ui/groups/</guid><description>&lt;p&gt;The &lt;strong&gt;Groups&lt;/strong&gt; page lets you define Nebula security groups and their &lt;strong&gt;inbound firewall rules&lt;/strong&gt; per network. Groups are used by nodes (each node has one group). Firewall rules control which other groups can send traffic to this group and on what protocol and ports.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Light&lt;/th&gt;
 &lt;th&gt;Dark&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/groups.png" alt="Groups page"&gt;&lt;/td&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/dark/groups.png" alt="Groups page in dark mode"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="selecting-a-network"&gt;Selecting a network&lt;/h2&gt;
&lt;p&gt;At the top of the Groups page, choose a &lt;strong&gt;network&lt;/strong&gt; from the dropdown. Groups and rules are per network. Only networks you have access to appear in the list.&lt;/p&gt;</description></item><item><title>Managing your membership</title><link>https://nebulacommander.com/docs/cloud/managing-membership/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/cloud/managing-membership/</guid><description>&lt;h2 id="signing-in-to-your-account"&gt;Signing in to your account&lt;/h2&gt;
&lt;p&gt;Your account at &lt;a href="https://cloud.nebulacdr.net/"&gt;cloud.nebulacdr.net&lt;/a&gt; is where you manage billing.
It&amp;rsquo;s separate from your instance, which you use at &lt;code&gt;your-name.nebulacdr.net&lt;/code&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://cloud.nebulacdr.net/login"&gt;cloud.nebulacdr.net/login&lt;/a&gt; and enter the email you
signed up with.&lt;/li&gt;
&lt;li&gt;Open the sign-in link we email you. It expires after 15 minutes.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The account page lists your instances with their status and current price.&lt;/p&gt;
&lt;h2 id="updating-your-card-and-downloading-invoices"&gt;Updating your card and downloading invoices&lt;/h2&gt;
&lt;p&gt;On the account page, click &lt;strong&gt;Manage billing&lt;/strong&gt;. This opens Stripe&amp;rsquo;s secure billing page, where you
can:&lt;/p&gt;</description></item><item><title>NixOS</title><link>https://nebulacommander.com/docs/installation/nixos/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/installation/nixos/</guid><description>&lt;p&gt;Run Nebula Commander as a NixOS service by adding the module and enabling the service. You can add the module from a local path (clone) or, when available, from a flake.&lt;/p&gt;
&lt;h2 id="adding-the-module-path-based-no-flake"&gt;Adding the module (path-based, no flake)&lt;/h2&gt;
&lt;p&gt;Use this when you have the nebula-commander repository on disk (for example under &lt;code&gt;/etc/nixos&lt;/code&gt; or a path you manage).&lt;/p&gt;
&lt;h3 id="1-get-the-repository"&gt;1. Get the repository&lt;/h3&gt;
&lt;p&gt;Clone or copy the nebula-commander repo so that the path contains both &lt;code&gt;nix/&lt;/code&gt; and &lt;code&gt;backend/&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>OIDC Authentication</title><link>https://nebulacommander.com/docs/configuration/oidc/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/configuration/oidc/</guid><description>&lt;p&gt;Nebula Commander can use OpenID Connect (OIDC) for login. Keycloak is supported with a pre-configured setup; other OIDC providers (Authentik, Auth0, etc.) work with the same environment variables.&lt;/p&gt;
&lt;h2 id="required-variables"&gt;Required variables&lt;/h2&gt;
&lt;p&gt;Set these in &lt;code&gt;env.d/backend&lt;/code&gt; (Docker) or in the backend environment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;NEBULA_COMMANDER_PUBLIC_URL&lt;/code&gt;&lt;/strong&gt; – URL where users reach the app (FQDN or host:port). The redirect URI is derived as PUBLIC_URL + &lt;code&gt;/api/auth/callback&lt;/code&gt; if you do not set &lt;code&gt;OIDC_REDIRECT_URI&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;NEBULA_COMMANDER_OIDC_ISSUER_URL&lt;/code&gt;&lt;/strong&gt; – Issuer URL used by the &lt;strong&gt;backend&lt;/strong&gt; to talk to the provider. Inside Docker use the container name and container port (e.g. &lt;code&gt;http://keycloak:8080/realms/nebula-commander&lt;/code&gt;). Do not use the host-mapped port here.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;NEBULA_COMMANDER_OIDC_PUBLIC_ISSUER_URL&lt;/code&gt;&lt;/strong&gt; – Issuer URL as seen by the &lt;strong&gt;browser&lt;/strong&gt; (FQDN or host:port). Use the same URL users would use to open the provider’s login page.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;NEBULA_COMMANDER_OIDC_CLIENT_ID&lt;/code&gt;&lt;/strong&gt; – OIDC client ID (e.g. &lt;code&gt;nebula-commander&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;NEBULA_COMMANDER_OIDC_CLIENT_SECRET&lt;/code&gt;&lt;/strong&gt; – Client secret from the provider. Prefer &lt;code&gt;NEBULA_COMMANDER_OIDC_CLIENT_SECRET_FILE&lt;/code&gt; in production.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Optional: &lt;strong&gt;&lt;code&gt;NEBULA_COMMANDER_OIDC_REDIRECT_URI&lt;/code&gt;&lt;/strong&gt; – Override only if you need a callback URL different from PUBLIC_URL + &lt;code&gt;/api/auth/callback&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>DNS</title><link>https://nebulacommander.com/docs/web-ui/dns/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/web-ui/dns/</guid><description>&lt;p&gt;The &lt;strong&gt;DNS&lt;/strong&gt; page configures &lt;strong&gt;split-horizon DNS&lt;/strong&gt; per network: a domain and optional hostname aliases that resolve to nodes inside the Nebula overlay. When enabled, lighthouses (or the Docker ncclient stack) can run dnsmasq to serve this domain; enrolled devices can use &lt;a href="https://nebulacommander.com/docs/usage/ncclient/usage/cli/#split-horizon-dns"&gt;ncclient with &lt;code&gt;--accept-dns&lt;/code&gt;&lt;/a&gt; to resolve the Nebula domain via the overlay.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Light&lt;/th&gt;
 &lt;th&gt;Dark&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/dns.png" alt="DNS page"&gt;&lt;/td&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/dark/dns.png" alt="DNS page in dark mode"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="access"&gt;Access&lt;/h2&gt;
&lt;p&gt;Only &lt;strong&gt;network owners&lt;/strong&gt; can view or change DNS for a network. Select a network from the dropdown at the top; the page shows the current DNS config and aliases for that network.&lt;/p&gt;</description></item><item><title>Linux Desktop App</title><link>https://nebulacommander.com/docs/usage/ncclient/installation/linux/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/ncclient/installation/linux/</guid><description>&lt;p&gt;On Linux, three packages give you a GTK4/libadwaita desktop app plus a background systemd service that does the actual work - no group membership or relogin needed, and no admin/root prompt for enrolling, starting/stopping, or accepting routes.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Light&lt;/th&gt;
 &lt;th&gt;Dark&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/apps/linux-networks.png" alt="Linux desktop app"&gt;&lt;/td&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/dark/apps/linux-networks.png" alt="Linux desktop app in dark mode"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;What&amp;rsquo;s included:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;nebula-commander-client&lt;/strong&gt; – The &lt;code&gt;ncclient&lt;/code&gt; CLI (frozen binary, no Python runtime needed).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;nebula-commander-service&lt;/strong&gt; – Installs &lt;code&gt;ncclient.service&lt;/code&gt; (systemd), which polls for config/certs and runs Nebula as root. Exposes a system D-Bus API (&lt;code&gt;org.beardedtek.NebulaCommander1&lt;/code&gt;) that the desktop app talks to, authorized per-call via polkit.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;nebula-commander-desktop&lt;/strong&gt; – The GTK4 app: enroll, view connection/service status, and accept or reject offered subnet routes and exit nodes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Any user logged in at the machine can view status in the desktop app. Changes (enrolling, settings, routes, exit node, starting/stopping the service) need no password for members of the &lt;code&gt;sudo&lt;/code&gt; or &lt;code&gt;wheel&lt;/code&gt; group, which administrators normally already are, and an administrator&amp;rsquo;s password for everyone else.&lt;/p&gt;</description></item><item><title>Subnet Routers and Exit Nodes</title><link>https://nebulacommander.com/docs/usage/unsafe-routes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/unsafe-routes/</guid><description>&lt;p&gt;Nebula Commander can turn a node into a &lt;strong&gt;subnet router&lt;/strong&gt; (it advertises a LAN behind it
to the rest of the mesh, the way &lt;code&gt;tailscale up --advertise-routes&lt;/code&gt; does) or an &lt;strong&gt;exit
node&lt;/strong&gt; (it advertises &lt;code&gt;0.0.0.0/0&lt;/code&gt;/&lt;code&gt;::/0&lt;/code&gt; and routes all of another node&amp;rsquo;s traffic, the
way &lt;code&gt;tailscale up --advertise-exit-node&lt;/code&gt; does). Both build on Nebula&amp;rsquo;s own
&lt;a href="https://nebula.defined.net/docs/config/tun/#tununsafe_routes"&gt;&lt;code&gt;unsafe_routes&lt;/code&gt;&lt;/a&gt; feature.&lt;/p&gt;
&lt;p&gt;This page covers how it&amp;rsquo;s configured from both sides — the gateway that advertises a
route, and the other nodes that actually use it — what happens automatically for
nodes running &lt;a href="https://nebulacommander.com/docs/usage/ncclient/"&gt;ncclient&lt;/a&gt; on Linux, and — the part that&amp;rsquo;s easy to miss — what you
have to do yourself for everything else (Windows, macOS, Docker-deployed &lt;code&gt;ncclient&lt;/code&gt;,
or bare &lt;code&gt;nebula&lt;/code&gt;).&lt;/p&gt;</description></item><item><title>Public Endpoints and Reachable Addresses</title><link>https://nebulacommander.com/docs/usage/reachable-addresses/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/reachable-addresses/</guid><description>&lt;p&gt;Nebula finds most nodes on its own: each node reports the addresses of its local
interfaces to the lighthouses, and the lighthouses also see the address a node
connects to them from. Three optional per-node settings cover what that misses. They
reach other nodes by different paths, so they&amp;rsquo;re separate fields. A fourth setting,
the &lt;a href="https://nebulacommander.com/docs/usage/reachable-addresses/#listen-port"&gt;listen port&lt;/a&gt;, is the UDP port the node itself binds.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;Public endpoint&lt;/th&gt;
 &lt;th&gt;Additional endpoints&lt;/th&gt;
 &lt;th&gt;Additional reachable addresses&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Where to set it&lt;/td&gt;
 &lt;td&gt;&lt;a href="https://nebulacommander.com/docs/web-ui/nodes/#the-node-details-panel"&gt;Node details panel&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;Node details panel, once a public endpoint is set&lt;/td&gt;
 &lt;td&gt;Node details → &lt;strong&gt;Advanced&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Values&lt;/td&gt;
 &lt;td&gt;One &lt;code&gt;host:port&lt;/code&gt; (hostname, IPv4, or &lt;code&gt;[IPv6]&lt;/code&gt;)&lt;/td&gt;
 &lt;td&gt;Up to 8 &lt;code&gt;host:port&lt;/code&gt;, added one at a time&lt;/td&gt;
 &lt;td&gt;Up to 8 &lt;code&gt;IP:port&lt;/code&gt;, added one at a time&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Nebula setting&lt;/td&gt;
 &lt;td&gt;Every peer&amp;rsquo;s &lt;a href="https://nebula.defined.net/docs/config/static-host-map/"&gt;&lt;code&gt;static_host_map&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;Every peer&amp;rsquo;s &lt;code&gt;static_host_map&lt;/code&gt;, after the public endpoint&lt;/td&gt;
 &lt;td&gt;This node&amp;rsquo;s own &lt;a href="https://nebula.defined.net/docs/config/lighthouse/#lighthouseadvertise_addrs"&gt;&lt;code&gt;lighthouse.advertise_addrs&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;How other nodes learn it&lt;/td&gt;
 &lt;td&gt;Written into their config&lt;/td&gt;
 &lt;td&gt;Written into their config&lt;/td&gt;
 &lt;td&gt;Reported to the lighthouses, which pass it on&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Lighthouses and relays&lt;/td&gt;
 &lt;td&gt;Need one&lt;/td&gt;
 &lt;td&gt;Allowed&lt;/td&gt;
 &lt;td&gt;Not shown (Nebula ignores it on lighthouses)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Changing it restarts Nebula on&lt;/td&gt;
 &lt;td&gt;Every node on the network&lt;/td&gt;
 &lt;td&gt;Every node on the network&lt;/td&gt;
 &lt;td&gt;That node only&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;They can be used together: the endpoints let peers reach a node without asking a
lighthouse first, and the additional reachable addresses fill in paths the
lighthouses can&amp;rsquo;t see.&lt;/p&gt;</description></item><item><title>Manual Builds</title><link>https://nebulacommander.com/docs/development/manual-builds/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/development/manual-builds/</guid><description>&lt;p&gt;You can build all ncclient binaries, the Windows service and app, the Windows MSI, the Linux &lt;code&gt;.deb&lt;/code&gt;/&lt;code&gt;.rpm&lt;/code&gt;/Flatpak packages, and the Docker images locally without using GitHub Actions.&lt;/p&gt;
&lt;h2 id="ncclient-cli-standalone-binary"&gt;ncclient CLI (standalone binary)&lt;/h2&gt;
&lt;p&gt;The CLI is built with PyInstaller from &lt;code&gt;client/binaries/&lt;/code&gt;. Python 3.11 is used in CI.&lt;/p&gt;
&lt;h3 id="same-platform-linux-x86_64-windows-x86_64-macos"&gt;Same platform (Linux x86_64, Windows x86_64, macOS)&lt;/h3&gt;
&lt;p&gt;From the repository root:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pip install -r client/binaries/requirements.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pip install -r client/requirements.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd client/binaries
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;python build.py
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Output: &lt;code&gt;client/binaries/dist/ncclient&lt;/code&gt; (or &lt;code&gt;ncclient.exe&lt;/code&gt; on Windows). Use &lt;code&gt;python build.py --clean&lt;/code&gt; to remove build artifacts; &lt;code&gt;python build.py --test&lt;/code&gt; to build and run basic tests.&lt;/p&gt;</description></item><item><title>Running Nebula manually</title><link>https://nebulacommander.com/docs/usage/nebula/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/nebula/</guid><description>&lt;p&gt;This is the &lt;strong&gt;manual&lt;/strong&gt; method: you use Nebula Commander to create networks, nodes, and certificates, then run &lt;a href="https://github.com/slackhq/nebula"&gt;Nebula&lt;/a&gt; on devices yourself without ncclient. Config and certs are copied or downloaded from the UI (or API) and you start Nebula manually. Use this when you prefer to deploy config and certs yourself or when ncclient is not available (e.g. on mobile).&lt;/p&gt;
&lt;h2 id="when-to-use-this"&gt;When to use this&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;You prefer to deploy config and certs yourself (copy to the device, run &lt;code&gt;nebula -config ...&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;You do not want to enroll devices or run the ncclient daemon.&lt;/li&gt;
&lt;li&gt;You are fine updating config and certs manually when the network or node changes (re-download from the UI or API and replace files, then restart Nebula).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With &lt;a href="https://nebulacommander.com/docs/usage/ncclient/"&gt;ncclient&lt;/a&gt;, the device enrolls once and ncclient polls for config and certs and can run or restart Nebula automatically. With manual setup, you handle file deployment and restarts yourself.&lt;/p&gt;</description></item><item><title>NixOS</title><link>https://nebulacommander.com/docs/usage/ncclient/usage/nixos/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/ncclient/usage/nixos/</guid><description>&lt;p&gt;This page covers day-to-day use of the &lt;code&gt;services.ncclient&lt;/code&gt; module. See &lt;a href="https://nebulacommander.com/docs/usage/ncclient/installation/nixos/"&gt;NixOS installation&lt;/a&gt; for importing the module and its full option list. Paths below use the defaults (&lt;code&gt;stateDir = &amp;quot;/var/lib/ncclient&amp;quot;&lt;/code&gt;, &lt;code&gt;outputDir = &amp;quot;/var/lib/ncclient/nebula&amp;quot;&lt;/code&gt;); adjust them if you changed those options.&lt;/p&gt;
&lt;h2 id="what-the-module-sets-up"&gt;What the module sets up&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ncclient.service&lt;/code&gt;: runs &lt;code&gt;ncclient run&lt;/code&gt; as root, with &lt;code&gt;nebula&lt;/code&gt; from &lt;code&gt;nebulaPackage&lt;/code&gt;, plus &lt;code&gt;nftables&lt;/code&gt; and &lt;code&gt;iproute2&lt;/code&gt; (for subnet-router/exit-node forwarding and NAT), on its PATH. It restarts on failure.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ncclient-enroll.service&lt;/code&gt;: only when &lt;code&gt;enrollCodeFile&lt;/code&gt; or &lt;code&gt;networks&lt;/code&gt; is set. A oneshot that runs &lt;code&gt;ncclient enroll&lt;/code&gt; before the main service, &lt;strong&gt;once per network&lt;/strong&gt;: after enrolling it writes a marker file (&lt;code&gt;/var/lib/ncclient/.enrolled-&amp;lt;name&amp;gt;&lt;/code&gt;) and never sends that network&amp;rsquo;s code again.&lt;/li&gt;
&lt;li&gt;The D-Bus policy and polkit rules the &lt;a href="https://nebulacommander.com/docs/usage/ncclient/usage/linux/"&gt;Linux desktop app&lt;/a&gt; uses, if you also enable &lt;code&gt;services.ncclient-desktop&lt;/code&gt;. Only members of &lt;code&gt;adminGroups&lt;/code&gt; (default &lt;code&gt;wheel&lt;/code&gt;/&lt;code&gt;sudo&lt;/code&gt;) can make changes without a password.&lt;/li&gt;
&lt;li&gt;An &lt;code&gt;ncclient&lt;/code&gt; command on the system PATH, pre-pointed at the service&amp;rsquo;s state. See &lt;a href="https://nebulacommander.com/docs/usage/ncclient/usage/nixos/#running-ncclient-commands"&gt;Running ncclient commands&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="where-state-lives"&gt;Where state lives&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Path&lt;/th&gt;
 &lt;th&gt;What it is&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/var/lib/ncclient/tokens/&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;One device token per network&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/var/lib/ncclient/settings.json&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Each network&amp;rsquo;s server, node ID and accepted routes&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/var/lib/ncclient/.enrolled-&amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Marker: the enroll unit has enrolled network &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;/var/lib/ncclient/nebula/networks/&amp;lt;id&amp;gt;/&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Each network&amp;rsquo;s Nebula &lt;code&gt;config.yaml&lt;/code&gt;, certificates, status&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Both directories are &lt;code&gt;0700 root:root&lt;/code&gt;. Before v0.8.0 the token was &lt;code&gt;/var/lib/ncclient/token&lt;/code&gt; and the Nebula files were directly in &lt;code&gt;nebula/&lt;/code&gt;; ncclient moves them into this layout on its first start.&lt;/p&gt;</description></item><item><title>Nodes</title><link>https://nebulacommander.com/docs/web-ui/nodes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/web-ui/nodes/</guid><description>&lt;p&gt;The &lt;strong&gt;Nodes&lt;/strong&gt; page shows every node across networks (or filtered to one network) as
a grid of square cards. You create nodes, assign IPs and groups, create or sign
certificates, generate &lt;strong&gt;enrollment codes&lt;/strong&gt; for &lt;a href="https://nebulacommander.com/docs/usage/ncclient/"&gt;ncclient&lt;/a&gt;,
download config, and — new since v0.3.7 — pick which other node each one should
route through as a &lt;a href="https://nebulacommander.com/docs/usage/unsafe-routes/"&gt;subnet router or exit node&lt;/a&gt;.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Light&lt;/th&gt;
 &lt;th&gt;Dark&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/nodes.png" alt="Nodes page"&gt;&lt;/td&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/dark/nodes.png" alt="Nodes page in dark mode"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="the-node-grid"&gt;The node grid&lt;/h2&gt;
&lt;p&gt;Each card is color-coded by status — never checked in, active, or inactive — and
carries a bottom-right badge cluster: &lt;strong&gt;Lighthouse&lt;/strong&gt;, &lt;strong&gt;Relay&lt;/strong&gt;, and a type/OS badge
(&lt;strong&gt;iOS&lt;/strong&gt;, &lt;strong&gt;Android&lt;/strong&gt;, &lt;strong&gt;Windows&lt;/strong&gt;, &lt;strong&gt;Linux&lt;/strong&gt;, &lt;strong&gt;macOS&lt;/strong&gt;, or a generic &lt;strong&gt;Node&lt;/strong&gt;
fallback until the platform is known). Hostname and IP sit at the top of the card,
always drawn above the badges so a long badge row can never hide them, even on a
narrow phone screen. Click a card to open its details panel:&lt;/p&gt;</description></item><item><title>Reverse Proxy</title><link>https://nebulacommander.com/docs/installation/reverse-proxy/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/installation/reverse-proxy/</guid><description>&lt;p&gt;Nebula Commander is typically run &lt;strong&gt;behind a reverse proxy&lt;/strong&gt; such as Nginx, Traefik, or Caddy.
The frontend and backend containers listen on plain HTTP inside Docker; your reverse proxy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Terminates TLS on port 443 with a certificate&lt;/li&gt;
&lt;li&gt;Proxies requests to the frontend container (and through it to the backend)&lt;/li&gt;
&lt;li&gt;Adds security headers like &lt;code&gt;Strict-Transport-Security&lt;/code&gt; (HSTS)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This page shows recommended HSTS settings and example reverse proxy configurations.&lt;/p&gt;
&lt;h2 id="hsts-and-https"&gt;HSTS and HTTPS&lt;/h2&gt;
&lt;p&gt;For best security, configure HTTPS and HSTS on &lt;strong&gt;your reverse proxy&lt;/strong&gt;, not inside the containers.
That lets you choose the right TLS policy for your environment (LAN-only, VPN-only, or Internet-facing).&lt;/p&gt;</description></item><item><title>Windows Installer</title><link>https://nebulacommander.com/docs/usage/ncclient/installation/windows/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/ncclient/installation/windows/</guid><description>&lt;p&gt;On Windows the MSI installer sets up the ncclient CLI, a native windowed app, and a background Windows Service that does the actual work as &lt;code&gt;LocalSystem&lt;/code&gt;. Any user can view status in the app; enrolling, changing settings or routes, and starting/stopping the service require running the app as administrator.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://nebulacommander.com/screenshots/apps/windows-networks.png" alt="Nebula Commander Windows app"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What the installer includes:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ncclient&lt;/strong&gt; – CLI for enrollment and daemon (poll for config/certs, run or restart Nebula).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nebula Commander&lt;/strong&gt; (WinUI 3) – The windowed desktop app: side tabs for Status, Enrollment, and Settings, minimizes to the tray on close. Talks to the background service.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ncclient-service&lt;/strong&gt; – The &lt;code&gt;NebulaCommanderService&lt;/code&gt; Windows Service that polls for config/certs and runs Nebula as &lt;code&gt;LocalSystem&lt;/code&gt;. Starts automatically at boot; the app talks to it over a local named pipe.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All three are installed to &lt;code&gt;%ProgramFiles%\Nebula Commander\&lt;/code&gt;. The installer can add that directory to PATH, creates Start Menu shortcuts, and registers/starts the service.&lt;/p&gt;</description></item><item><title>API</title><link>https://nebulacommander.com/docs/development/api/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/development/api/</guid><description>&lt;p&gt;The Nebula Commander backend exposes a REST API under the base path &lt;strong&gt;&lt;code&gt;/api&lt;/code&gt;&lt;/strong&gt;. All routes are prefixed with &lt;code&gt;/api&lt;/code&gt;. Most endpoints require a valid JWT in the &lt;code&gt;Authorization: Bearer &amp;lt;token&amp;gt;&lt;/code&gt; header unless noted otherwise.&lt;/p&gt;
&lt;h2 id="openapi-docs"&gt;OpenAPI docs&lt;/h2&gt;
&lt;p&gt;The backend serves interactive documentation at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Swagger UI&lt;/strong&gt; – /api/docs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ReDoc&lt;/strong&gt; – /api/redoc&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenAPI schema&lt;/strong&gt; – /api/openapi.json&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For full request/response schemas and parameters, use the interactive docs. They&amp;rsquo;re on by default; set &lt;a href="https://nebulacommander.com/docs/configuration/environment/#application"&gt;&lt;code&gt;NEBULA_COMMANDER_API_DOCS_ENABLED&lt;/code&gt;&lt;/a&gt; to &lt;code&gt;false&lt;/code&gt; (NixOS: &lt;code&gt;apiDocs = false;&lt;/code&gt;) to turn all three off. Before v0.9.0 the docs pages loaded the schema from &lt;code&gt;/openapi.json&lt;/code&gt;, which a reverse proxy usually sends to the frontend, so they didn&amp;rsquo;t render.&lt;/p&gt;</description></item><item><title>Client Download</title><link>https://nebulacommander.com/docs/web-ui/client-download/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/web-ui/client-download/</guid><description>&lt;p&gt;The &lt;strong&gt;Client Download&lt;/strong&gt; page (also reachable from the sidebar or at &lt;code&gt;/client-download&lt;/code&gt;) lets users download &lt;strong&gt;ncclient&lt;/strong&gt; binaries served directly from your Nebula Commander instance. No internet access to GitHub is required after deployment.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Light&lt;/th&gt;
 &lt;th&gt;Dark&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/client-download.png" alt="Client Download page"&gt;&lt;/td&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/dark/client-download.png" alt="Client Download page in dark mode"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="purpose"&gt;Purpose&lt;/h2&gt;
&lt;p&gt;Install and run ncclient on a device to enroll with Nebula Commander and pull config and certificates. The enrollment code is obtained from the &lt;a href="https://nebulacommander.com/docs/web-ui/nodes/"&gt;Nodes&lt;/a&gt; page (Enroll button for the node). The page is organized into tabs (Docker, Linux, Windows, macOS, Mobile) and provides the CLI for every platform, the Linux desktop app packages, and the Windows installer. Commands on the page are filled in with this instance&amp;rsquo;s own URL, so they can be pasted as-is.&lt;/p&gt;</description></item><item><title>Linux App</title><link>https://nebulacommander.com/docs/usage/ncclient/usage/linux/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/ncclient/usage/linux/</guid><description>&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Light&lt;/th&gt;
 &lt;th&gt;Dark&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/apps/linux-networks.png" alt="Linux app Networks tab, enrolled in two networks"&gt;&lt;/td&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/dark/apps/linux-networks.png" alt="Linux app Networks tab in dark mode"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;On Linux, &lt;strong&gt;Nebula Commander&lt;/strong&gt; (GTK4/libadwaita) is an unelevated desktop app for the background &lt;strong&gt;ncclient&lt;/strong&gt; systemd service. The service does the actual work (polling for config and certs, running Nebula) as root, and exposes a system D-Bus API (&lt;code&gt;org.beardedtek.NebulaCommander1&lt;/code&gt;) that the app talks to, authorized per call via polkit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anyone can view; administrators change.&lt;/strong&gt; Any user logged in at the machine can see status and offered routes. Enrolling, changing settings, accepting routes or exit nodes, and starting/stopping the service work without a password for members of the &lt;strong&gt;&lt;code&gt;sudo&lt;/code&gt;&lt;/strong&gt; (Debian/Ubuntu) or &lt;strong&gt;&lt;code&gt;wheel&lt;/code&gt;&lt;/strong&gt; (Fedora/openSUSE/Arch) group. Anyone else needs an administrator&amp;rsquo;s password, so other users of a shared machine can&amp;rsquo;t re-point or stop the tunnel. Remote (SSH) sessions get nothing through the app&amp;rsquo;s API; use &lt;code&gt;sudo&lt;/code&gt; on the command line instead.&lt;/p&gt;</description></item><item><title>NixOS</title><link>https://nebulacommander.com/docs/usage/ncclient/installation/nixos/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/ncclient/installation/nixos/</guid><description>&lt;p&gt;A &lt;code&gt;services.ncclient&lt;/code&gt; module runs ncclient declaratively as a systemd service — an alternative to the Docker image, the Windows service, or a hand-written unit (see &lt;a href="https://nebulacommander.com/docs/usage/ncclient/usage/cli/#run-as-a-service"&gt;ncclient CLI: Run as a service&lt;/a&gt;). It&amp;rsquo;s exposed by the same &lt;code&gt;flake.nix&lt;/code&gt; as the &lt;a href="https://nebulacommander.com/docs/installation/nixos/#adding-via-a-flake"&gt;server module&lt;/a&gt;, as &lt;code&gt;nixosModules.client&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-nix" data-lang="nix"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; inputs&lt;span style="color:#f92672"&gt;.&lt;/span&gt;nebula-commander&lt;span style="color:#f92672"&gt;.&lt;/span&gt;url &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;github:nebula-commander/nebula-commander&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; outputs &lt;span style="color:#f92672"&gt;=&lt;/span&gt; { self&lt;span style="color:#f92672"&gt;,&lt;/span&gt; nixpkgs&lt;span style="color:#f92672"&gt;,&lt;/span&gt; nebula-commander&lt;span style="color:#f92672"&gt;,&lt;/span&gt; &lt;span style="color:#f92672"&gt;...&lt;/span&gt; }: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; nixosConfigurations&lt;span style="color:#f92672"&gt;.&lt;/span&gt;yourHost &lt;span style="color:#f92672"&gt;=&lt;/span&gt; nixpkgs&lt;span style="color:#f92672"&gt;.&lt;/span&gt;lib&lt;span style="color:#f92672"&gt;.&lt;/span&gt;nixosSystem {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; system &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;x86_64-linux&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; modules &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;./configuration.nix&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; nebula-commander&lt;span style="color:#f92672"&gt;.&lt;/span&gt;nixosModules&lt;span style="color:#f92672"&gt;.&lt;/span&gt;client
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or import &lt;code&gt;nix/client-module.nix&lt;/code&gt; directly by path if you&amp;rsquo;re not using a flake, the same way the &lt;a href="https://nebulacommander.com/docs/installation/nixos/#adding-the-module-path-based-no-flake"&gt;server module&lt;/a&gt; can be.&lt;/p&gt;</description></item><item><title>Invitations</title><link>https://nebulacommander.com/docs/web-ui/invitations/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/web-ui/invitations/</guid><description>&lt;p&gt;The &lt;strong&gt;Invitations&lt;/strong&gt; page lets network owners (and system admins) invite users to a network with a chosen &lt;strong&gt;role&lt;/strong&gt; and permissions. Invitations work when OIDC is configured; invited users sign in via the IdP and then gain access to the specified network.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Light&lt;/th&gt;
 &lt;th&gt;Dark&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/invitations-send.png" alt="Invitations – send invite"&gt;&lt;/td&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/dark/invitations-send.png" alt="Invitations – send invite, dark mode"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="what-invitations-are"&gt;What invitations are&lt;/h2&gt;
&lt;p&gt;An invitation associates an &lt;strong&gt;email&lt;/strong&gt; (or link) with a &lt;strong&gt;network&lt;/strong&gt;, a &lt;strong&gt;role&lt;/strong&gt; (e.g. member, admin), and optional &lt;strong&gt;permissions&lt;/strong&gt; (can manage nodes, can invite users, can manage firewall). The invitee accepts by clicking a link or using a token; after acceptance they appear as a user with access to that network according to the role and permissions.&lt;/p&gt;</description></item><item><title>Pip (PyPI)</title><link>https://nebulacommander.com/docs/usage/ncclient/installation/pip/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/ncclient/installation/pip/</guid><description>&lt;p&gt;&lt;strong&gt;For advanced users only.&lt;/strong&gt; Pip is the most delicate way to install ncclient. It&amp;rsquo;s easy to end up with a setup that &lt;code&gt;sudo&lt;/code&gt; can&amp;rsquo;t find, that root can&amp;rsquo;t safely run, or that stores the token somewhere the service doesn&amp;rsquo;t look. Use the &lt;a href="https://nebulacommander.com/docs/usage/ncclient/installation/linux/"&gt;Linux packages&lt;/a&gt;, the &lt;a href="https://nebulacommander.com/docs/usage/ncclient/installation/windows/"&gt;Windows installer&lt;/a&gt;, &lt;a href="https://nebulacommander.com/docs/usage/ncclient/installation/docker/"&gt;Docker&lt;/a&gt;, or the &lt;a href="https://nebulacommander.com/docs/usage/ncclient/installation/binaries/"&gt;binaries&lt;/a&gt; unless you need to run from source or none of those fit.&lt;/p&gt;
&lt;p&gt;From PyPI:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pip install nebula-commander
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Requires Python 3.10+. This installs the &lt;code&gt;ncclient&lt;/code&gt; command.&lt;/p&gt;</description></item><item><title>Windows App</title><link>https://nebulacommander.com/docs/usage/ncclient/usage/windows/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/ncclient/usage/windows/</guid><description>&lt;p&gt;&lt;img src="https://nebulacommander.com/screenshots/apps/windows-networks.png" alt="Windows app Networks page, enrolled in two networks"&gt;&lt;/p&gt;
&lt;p&gt;On Windows, &lt;strong&gt;Nebula Commander&lt;/strong&gt; (WinUI 3) is a native windowed app for a background &lt;strong&gt;Windows Service&lt;/strong&gt; (&lt;code&gt;NebulaCommanderService&lt;/code&gt;). The service does the actual work (polling for config and certs, running Nebula, applying split-horizon DNS) as &lt;code&gt;LocalSystem&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Anyone can view; only administrators can change.&lt;/strong&gt; Run normally, the app is view-only: status, routes and config are visible to every user. Enrolling, changing settings, accepting routes or exit nodes, installing/updating Nebula, and starting/stopping the service all require an &lt;strong&gt;elevated administrator&lt;/strong&gt;. Use the &lt;strong&gt;Relaunch as administrator&lt;/strong&gt; bar at the top of the app (or press &lt;strong&gt;Alt+R&lt;/strong&gt;; one UAC prompt), or start it with &lt;strong&gt;Run as administrator&lt;/strong&gt;. The service enforces this itself on every change, so other users on a shared PC can&amp;rsquo;t re-point or stop your tunnel.&lt;/p&gt;</description></item><item><title>Several networks on one device</title><link>https://nebulacommander.com/docs/usage/ncclient/usage/networks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/ncclient/usage/networks/</guid><description>&lt;p&gt;From v0.8.0, one device can be in several networks at once, for example your own network plus a customer&amp;rsquo;s. The networks can be on the same Nebula Commander server or on different ones. You enroll once per network, with a code from that network&amp;rsquo;s Nebula Commander, and the one ncclient on the device runs them all.&lt;/p&gt;
&lt;p&gt;Each network gets its own Nebula process on its own interface, with its own token, config, certificates, routes and DNS. The desktop apps list them on a &lt;strong&gt;Networks&lt;/strong&gt; page.&lt;/p&gt;</description></item><item><title>Users</title><link>https://nebulacommander.com/docs/web-ui/users/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/web-ui/users/</guid><description>&lt;p&gt;The &lt;strong&gt;Users&lt;/strong&gt; page (&lt;strong&gt;sidebar → Users&lt;/strong&gt;) lists every user account in Nebula
Commander as a grid of square cards. It&amp;rsquo;s visible only to &lt;strong&gt;system admins&lt;/strong&gt; —
everyone else never sees this link.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Light&lt;/th&gt;
 &lt;th&gt;Dark&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/users.png" alt="Users page"&gt;&lt;/td&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/dark/users.png" alt="Users page in dark mode"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="the-user-grid"&gt;The user grid&lt;/h2&gt;
&lt;p&gt;Each card shows a user&amp;rsquo;s email, their &lt;strong&gt;system role&lt;/strong&gt; badge (&lt;code&gt;system-admin&lt;/code&gt; in red,
&lt;code&gt;user&lt;/code&gt; in gray), whether they use &lt;a href="https://nebulacommander.com/docs/web-ui/security/"&gt;two-factor login&lt;/a&gt;
(&lt;strong&gt;2FA on&lt;/strong&gt; or &lt;strong&gt;No 2FA&lt;/strong&gt;), and how many networks they belong to.
Click a card to open its details.&lt;/p&gt;</description></item><item><title>Security (two-factor login)</title><link>https://nebulacommander.com/docs/web-ui/security/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/web-ui/security/</guid><description>&lt;p&gt;From v0.9.0, every account can add &lt;strong&gt;two-factor authentication (2FA)&lt;/strong&gt;: after
signing in as usual, Nebula Commander asks for a 6-digit code from an
authenticator app on your phone. Someone who learns your password, or gets into
your identity provider account, still can&amp;rsquo;t get in without that code.&lt;/p&gt;
&lt;p&gt;It works with &lt;strong&gt;any authenticator app&lt;/strong&gt; that supports standard time-based codes
(TOTP): Google Authenticator, Microsoft Authenticator, Authy, 1Password,
Bitwarden, Aegis, Proton Pass and so on. It also works with any sign-in method
(Keycloak or another OIDC provider, or the standalone dev-token login), because
Nebula Commander checks the code itself.&lt;/p&gt;</description></item><item><title>Backup &amp; export</title><link>https://nebulacommander.com/docs/web-ui/backup/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/web-ui/backup/</guid><description>&lt;p&gt;The &lt;strong&gt;Backup &amp;amp; export&lt;/strong&gt; page (&lt;strong&gt;sidebar → Backup &amp;amp; export&lt;/strong&gt;) lets a system admin
download everything in a Nebula Commander instance as one encrypted file, and
import such a file into a new instance. Use it to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;keep an offline backup,&lt;/li&gt;
&lt;li&gt;move from hosted Nebula Commander to your own server (or the other way round),&lt;/li&gt;
&lt;li&gt;move a self-hosted instance to new hardware.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Only &lt;strong&gt;system admins&lt;/strong&gt; see this page, and both export and import ask you to
&lt;strong&gt;sign in again&lt;/strong&gt; before they run.&lt;/p&gt;</description></item><item><title>Move server</title><link>https://nebulacommander.com/docs/web-ui/move/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/web-ui/move/</guid><description>&lt;p&gt;From v0.9.0, a system admin can move a Nebula Commander instance to a new
address, and enrolled devices &lt;strong&gt;switch to the new server by themselves&lt;/strong&gt;, with
no re-enrollment and no editing of each device. Typical moves:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;https://nebulacdr.net&lt;/code&gt; to &lt;code&gt;https://beardedtek.nebulacdr.net&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nebulacommander.com/docs/cloud/"&gt;Nebula Commander Cloud&lt;/a&gt; to your own domain, your own server, or
an IP address (&lt;a href="https://nebulacommander.com/docs/web-ui/move/#leaving-nebula-commander-cloud"&gt;leaving Cloud&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;an old server to new hardware with a new hostname&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both servers run side by side for a while: the old one tells devices where to go,
and they move over during that time.&lt;/p&gt;</description></item><item><title>Appearance</title><link>https://nebulacommander.com/docs/web-ui/appearance/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/web-ui/appearance/</guid><description>&lt;p&gt;The &lt;strong&gt;Appearance&lt;/strong&gt; page (&lt;strong&gt;sidebar → Appearance&lt;/strong&gt;, or &lt;code&gt;/settings/appearance&lt;/code&gt;) lets
each user customize the colors used across Nebula Commander — this is a personal
preference, saved to your own account, not a site-wide setting an admin controls.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Light&lt;/th&gt;
 &lt;th&gt;Dark&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/appearance.png" alt="Appearance page"&gt;&lt;/td&gt;
 &lt;td&gt;&lt;img src="https://nebulacommander.com/screenshots/dark/appearance.png" alt="Appearance page in dark mode"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Every color you pick automatically gets a readable, contrast-checked
foreground: buttons, badges, status cards, and the page/container backgrounds
all compute their own text color (near-black or near-white) from whatever
background you choose, so an unusually light or dark pick never turns into
illegible same-on-same text.&lt;/p&gt;</description></item><item><title>Automatic updates</title><link>https://nebulacommander.com/docs/usage/ncclient/usage/auto-update/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/docs/usage/ncclient/usage/auto-update/</guid><description>&lt;p&gt;From v0.7.0, the client can keep itself up to date. It&amp;rsquo;s &lt;strong&gt;off by default&lt;/strong&gt;, and only an administrator on the device itself can turn it on. The Nebula Commander server shows each node&amp;rsquo;s client version and whether automatic updates are on, but can&amp;rsquo;t change the setting.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Install&lt;/th&gt;
 &lt;th&gt;What &amp;ldquo;on&amp;rdquo; does&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Windows (MSI)&lt;/td&gt;
 &lt;td&gt;The service downloads and installs new releases during a daily window you choose.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Linux deb/rpm from the &lt;a href="https://nebulacommander.com/docs/usage/ncclient/installation/linux/"&gt;package repository&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;A systemd timer upgrades the Nebula Commander packages from that repository during the window.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;NixOS module&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;Notify only.&lt;/strong&gt; Checks daily and tells you when a release is out, with the commands to update. It never changes the system: your flake decides the version.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Docker, Flatpak, pip, a bare binary&lt;/td&gt;
 &lt;td&gt;Not available. Update these the way you installed them (pull a new image, Flathub, &lt;code&gt;pip install -U&lt;/code&gt;).&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="turn-it-on"&gt;Turn it on&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Windows:&lt;/strong&gt; open the app as administrator (&lt;strong&gt;Relaunch as administrator&lt;/strong&gt;), go to &lt;strong&gt;Settings → Updates&lt;/strong&gt;, switch on &lt;strong&gt;Automatic updates&lt;/strong&gt;, pick the window and click &lt;strong&gt;Save&lt;/strong&gt;. Or, from an elevated prompt:&lt;/p&gt;</description></item><item><title>State of Nebula Commander Development (v0.4.0)</title><link>https://nebulacommander.com/blog/2026/09/16/2026-09-16-state-of-development-v0-4-0/</link><pubDate>Wed, 16 Sep 2026 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/blog/2026/09/16/2026-09-16-state-of-development-v0-4-0/</guid><description>&lt;p&gt;It&amp;rsquo;s been a little over two weeks since &lt;a href="https://nebulacommander.com/blog/2026/08/30/2026-08-30-state-of-development-v0-3-0/"&gt;the v0.3.0 update&lt;/a&gt;, where we listed &lt;strong&gt;exit nodes&lt;/strong&gt; as the one big thing still missing and called out a still-inconsistent UI as ongoing work. Neither of those is true anymore. This one covers &lt;strong&gt;v0.3.0 through v0.4.0&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="whats-new-since-v030"&gt;What&amp;rsquo;s new since v0.3.0&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Subnet routers and exit nodes are here&lt;/strong&gt;, built on Nebula&amp;rsquo;s own &lt;code&gt;unsafe_routes&lt;/code&gt;. Turn any node into a subnet router (advertise a LAN behind it, Tailscale-&lt;code&gt;--advertise-routes&lt;/code&gt;-style) or an exit node (route all of another node&amp;rsquo;s traffic, Tailscale-&lt;code&gt;--advertise-exit-node&lt;/code&gt;-style). Routes are opt-in per consumer — advertising one never silently exposes it network-wide — and configurable from either side: a gateway&amp;rsquo;s &amp;ldquo;Used by&amp;rdquo; picker, or, new in this release, a simple &lt;strong&gt;Use Subnet Router&lt;/strong&gt;/&lt;strong&gt;Use Exit Node&lt;/strong&gt; dropdown on any other node that wants to consume one, without opening the gateway&amp;rsquo;s own settings at all. On Linux nodes running &lt;code&gt;ncclient&lt;/code&gt;, the whole thing is automatic: local subnet discovery, IP forwarding, and nftables NAT rules, no host access needed. Everything else (Windows, macOS, Docker-deployed &lt;code&gt;ncclient&lt;/code&gt;, bare &lt;code&gt;nebula&lt;/code&gt;) gets the right config generated for it, with &lt;a href="https://nebulacommander.com/docs/usage/unsafe-routes/"&gt;a full doc&lt;/a&gt; on the manual host-side steps. Getting the Nebula semantics right here took two fix-forward releases early on — &lt;code&gt;via&lt;/code&gt; is mandatory on every &lt;code&gt;unsafe_routes&lt;/code&gt; entry and the gateway&amp;rsquo;s own certificate needs a &lt;code&gt;-subnets&lt;/code&gt; claim, or &lt;code&gt;nebula&lt;/code&gt; refuses to start at all.&lt;/p&gt;</description></item><item><title>State of Nebula Commander Development (v0.3.0)</title><link>https://nebulacommander.com/blog/2026/08/30/2026-08-30-state-of-development-v0-3-0/</link><pubDate>Sun, 30 Aug 2026 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/blog/2026/08/30/2026-08-30-state-of-development-v0-3-0/</guid><description>&lt;p&gt;It&amp;rsquo;s been a little over six months since our &lt;a href="https://nebulacommander.com/blog/2026/02/24/2026-02-24-state-of-development/"&gt;last state-of-development post&lt;/a&gt;, when we described Nebula Commander as being in &amp;ldquo;early development&amp;rdquo; with a client that was &amp;ldquo;still evolving.&amp;rdquo; Since then the project has moved through v0.2.12 all the way to &lt;strong&gt;v0.3.0&lt;/strong&gt;, and the picture has changed enough that it&amp;rsquo;s worth a proper update.&lt;/p&gt;
&lt;h2 id="whats-new-since-february"&gt;What&amp;rsquo;s new since February&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;The client is no longer the weak link.&lt;/strong&gt; The Windows client was rearchitected around a real background service (&lt;code&gt;NebulaCommanderService&lt;/code&gt;, running as &lt;code&gt;LocalSystem&lt;/code&gt;) with a thin, always-unelevated tray app on top — no UAC prompts, ever, for enrolling, starting Nebula, or applying DNS. It ships three ways now: a standalone CLI, the Windows MSI (CLI + tray + service), and a Docker image with an s6-overlay supervisor for lighthouse deployments.&lt;/p&gt;</description></item><item><title>State of Nebula Commander Development (February 2025)</title><link>https://nebulacommander.com/blog/2026/02/24/2026-02-24-state-of-development/</link><pubDate>Tue, 24 Feb 2026 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/blog/2026/02/24/2026-02-24-state-of-development/</guid><description>&lt;p&gt;Nebula Commander is a self-hosted control plane for &lt;a href="https://github.com/slackhq/nebula"&gt;Nebula&lt;/a&gt; overlay networks. This post summarizes where the project stands as of February 2026 and how you can try it or contribute.&lt;/p&gt;
&lt;h2 id="whats-in-place"&gt;What’s in place&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Backend (Python/FastAPI)&lt;/strong&gt;&lt;br&gt;
The API supports the core workflows: networks (create, delete), nodes (CRUD, IP allocation, certificates), groups and inbound firewall rules, and OIDC-based access with roles (system-admin, network-owner, user). You can run it with Docker, on NixOS via the systemd module, or locally with a venv and uvicorn.&lt;/p&gt;</description></item><item><title>Search</title><link>https://nebulacommander.com/search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://nebulacommander.com/search/</guid><description/></item></channel></rss>