Managing Daemons
Create, upgrade, and remove daemons.
Requirements
- Linux: Docker with host networking OR standalone binary (installable as a systemd service)
- macOS: Standalone binary — Docker Desktop doesn't allow access to host interfaces. Installs as a launchd service.
- Windows: Standalone binary — Docker Desktop doesn't allow access to host interfaces. Installs as a Windows service (native SCM).
- FreeBSD: Standalone binary, installable as an rc.d service.
On Linux, macOS, Windows, and FreeBSD the daemon installs as a native background service — see Running as a Service.
Creating a Daemon
Go to Discover > Scan > Daemons and click Create Daemon. The wizard walks you through:
- Setup — network, polling mode, and daemon name
- Integrations — optionally add credentials, targeting all hosts or specific ones. They're auto-assigned to discovered hosts after the first scan.
- Install — pick your platform and install method; the wizard builds the matching artifact for you
Finishing the wizard provisions the daemon: the server creates its record and mints an API key bound to it. You don't create a key yourself.
Choose an install method on the final step:
| Method | What you get |
|---|---|
| Linux / macOS / FreeBSD | A command that fetches the daemon binary and installs it as a native service |
| Windows | A PowerShell command that downloads the binary and installs it as a Windows service |
| Docker | A ready-to-run docker-compose.yml plus the SCANOPY_* environment variables it's configured with |
The generated artifact carries the daemon's API key, and the key is shown only here. Copy it before leaving the wizard — you can't retrieve it afterwards. If you lose it before installing, you can mint a replacement from the daemon's management modal; once the daemon has connected, re-keying it is blocked, because a fresh key would cut off the running daemon.
Any advanced settings you set in the wizard are baked into the artifact, so the installed daemon comes up already configured.
For help choosing a polling mode and planning where to place daemons, see Planning Daemon Deployment.
Running as a Service
scanopy-daemon install places the binary, writes the daemon's config.json, and registers a native background service that starts immediately and on every reboot — systemd on Linux, launchd on macOS, the Service Control Manager on Windows, rc.d on FreeBSD.
The command on the wizard's Install step already does this. Copy it from there rather than assembling one: the wizard and the management modal build it against your server's URL and the daemon's key.
Everything except the connection flags is read from config.json, so no secrets appear in the service definition or process arguments. Re-running install is idempotent. A non-elevated invocation prints the exact sudo/administrator command to re-run, and on success it prints the config and log paths it settled on.
Verify the service and view its logs:
- Linux:
systemctl status scanopy-daemon· logs viajournalctl -u scanopy-daemon -f - macOS:
sudo launchctl print system/com.scanopy.daemon· logs at/var/log/scanopy/scanopy-daemon.out.logand~/Library/Logs/scanopy/scanopy-daemon.log - Windows:
Get-Service scanopy-daemon· logs at%ProgramData%\scanopy\scanopy-daemon.log - FreeBSD:
service scanopy-daemon status
To stop and remove the service, use sudo scanopy-daemon uninstall — see Removing a Daemon.
Prefer to run the daemon in the foreground (e.g. for a quick test)? Run scanopy-daemon directly with the same flags — it runs attached to your terminal and stops when the terminal closes.
Running several daemons on one host? Each install takes its own numbered slot (scanopy-daemon, scanopy-daemon-2, …) automatically, so installs don't overwrite each other. Run scanopy-daemon list to see what's installed. See Scanning Isolated Networks from One Host for the full workflow.
Manually installed or older daemons
Daemons that predate the scanopy-daemon install subcommand, or that you set up by hand, are managed with the platform's native service tools directly. Use these instructions if scanopy-daemon install isn't available in your daemon version. (For current versions, prefer install/uninstall above.)
Linux (systemd, manual) — download the systemd unit, set your flags in ExecStart (or rely on config.json), then enable it:
sudo curl -o /etc/systemd/system/scanopy-daemon.service \
https://raw.githubusercontent.com/scanopy/scanopy/main/scanopy-daemon.service
sudo systemctl daemon-reload
sudo systemctl enable --now scanopy-daemonmacOS (launchd, manual) — create a launch daemon plist and load it:
sudo tee /Library/LaunchDaemons/com.scanopy.daemon.plist > /dev/null <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.scanopy.daemon</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/scanopy-daemon</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/var/log/scanopy/scanopy-daemon.out.log</string>
<key>StandardErrorPath</key>
<string>/var/log/scanopy/scanopy-daemon.out.log</string>
</dict>
</plist>
EOF
sudo launchctl bootstrap system /Library/LaunchDaemons/com.scanopy.daemon.plistWindows (NSSM, manual) — older setups used NSSM to run the executable as a service:
nssm install ScanopyDaemon "C:\Path\To\scanopy-daemon.exe"
nssm set ScanopyDaemon AppStdout "C:\ProgramData\scanopy\daemon.log"
nssm set ScanopyDaemon AppStderr "C:\ProgramData\scanopy\daemon.log"
nssm start ScanopyDaemonIntegrated Daemon (Self-Hosted)
Self-hosted Docker Compose deployments include an integrated daemon managed as part of the stack: server setup provisions it and its API key, and it upgrades with the server. Nothing to install or configure — see Upgrading a Self-Hosted Server.
Upgrading
When an update is available, the daemon card in Discover > Scan > Daemons shows an Update button, with the steps for your platform: download the latest binary, then restart the service. Configuration is preserved.
A Deprecated daemon has a scheduled sunset date, shown in the upgrade dialog with a countdown. Past that date it becomes Unsupported and is rejected until updated — see Daemon Status.
For upgrading self-hosted server and integrated daemon together, see Upgrading.
Updating Daemon Properties
Click the edit icon on a daemon card in Discover > Scan > Daemons to open its management modal, which has two tabs: Details for the daemon record, and API Key for its key.
The Details tab edits the maintainer, tags, and — for ServerPoll daemons — the URL the server dials. Network, polling mode, and name are read-only: they're set at provisioning and define what the daemon is. A DaemonPoll daemon has no URL to edit, since the server never dials it.
Daemon-local settings — interfaces, ports, log level, scan tuning — live in the daemon config file on the host, not on the server record. Change them by reconfiguring the daemon from the modal, or by editing config.json and restarting the service:
- Linux:
sudo systemctl restart scanopy-daemon - macOS:
sudo launchctl kickstart -k system/com.scanopy.daemon - Windows:
sc.exe stop scanopy-daemonthensc.exe start scanopy-daemon - FreeBSD:
sudo service scanopy-daemon restart
A foreground daemon just needs the process restarted.
Each daemon also reports which subnets it has network interfaces on, which is where its default scan targets come from. That list refreshes on its next discovery, so re-run one after changing the host's network configuration.
Reconfiguring a Daemon
Changing a daemon's advanced settings in the management modal produces a reconfigure artifact — the way settings you change in the app reach a daemon that's already installed.
A reconfigure differs from an install: it carries no API key and doesn't re-fetch the binary. It only re-asserts configuration, layering it over the config.json already on the host. For a Docker daemon you get just the environment variables that changed, to swap into your existing Compose file rather than replacing it — your own Compose customizations stay intact.
Run the artifact on the daemon host, then restart the service.
Binding a Key to a Legacy Daemon
Daemons set up before 1:1 provisioning authenticate with a key shared across every daemon on their network. They keep working indefinitely, but a shared key can't be rotated or revoked for one daemon without affecting the rest. Binding gives the daemon a key of its own, keeping its host, discovery jobs, and history.
Open the daemon's management modal, go to the API Key tab, and click Bind a Key. What happens next depends on the polling mode:
- DaemonPoll — the daemon keeps running on its shared key. You get a command to run on the daemon host to switch it over, and can do that whenever it suits you.
- ServerPoll — a hard cutover. The server starts using the new key to connect immediately, so the daemon stops responding until you reconfigure it. Only do this when you can get to the host right away.
Scanopy asks you to confirm before a ServerPoll cutover. See Daemon Identity for how the two key models coexist.
Removing a Daemon
To fully remove a daemon, delete it from the UI and uninstall it from the host.
Delete from the UI: Go to Discover > Scan > Daemons and click the delete icon on the daemon card.
Deleting or uninstalling a daemon does not delete discovered data. Hosts, services, subnets, and topology remain on the server until you explicitly delete them.
Uninstall from the host — for a daemon installed with scanopy-daemon install, run:
sudo scanopy-daemon uninstallThis stops and deregisters the service and deletes its config.json. Add --purge to also delete the binary and log files. On Windows, run it from an elevated PowerShell.
On a host running several daemons, target one with --name <selector> — its name, slot, or service id, all shown by scanopy-daemon list — or remove all of them with --all.
uninstall reports what it did with every item it touched, and is idempotent: uninstalling something that was never installed succeeds and says so.
Docker:
docker stop scanopy-daemon
docker rm scanopy-daemonManually installed or older daemons — if the daemon was set up by hand or predates the uninstall subcommand, remove the service and files manually.
Linux / macOS:
# systemd (Linux)
sudo systemctl stop scanopy-daemon && sudo systemctl disable scanopy-daemon
sudo rm /etc/systemd/system/scanopy-daemon.service && sudo systemctl daemon-reload
# launchd (macOS)
sudo launchctl bootout system /Library/LaunchDaemons/com.scanopy.daemon.plist
# (older setups: launchctl unload ~/Library/LaunchAgents/com.scanopy.daemon.plist)
# Remove binary and configuration
sudo rm /usr/local/bin/scanopy-daemon
rm -rf ~/.config/scanopy/ # Linux
rm -rf ~/Library/Application\ Support/com.scanopy.daemon/ # macOSWindows (NSSM or manual):
- Stop and remove the service:
nssm stop ScanopyDaemon && nssm remove ScanopyDaemon confirm(or stop the process) - Delete the executable
- Remove configuration from
%APPDATA%\scanopy\daemon\
Can I migrate a daemon?
No. Daemons discover host-specific data (network interfaces, Docker containers, local services) tied to the machine they run on. Moving a daemon's identity to a different host would produce inaccurate data.
If you're replacing a host, create a new daemon on the new machine and delete the old one.