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 SNMP, Docker, and Podman credentials, targeting all hosts or specific hosts. These are auto-assigned to discovered hosts after the first scan. See Credentials for details.
- 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
The recommended way to install the daemon is the scanopy-daemon install command. It places the binary, writes the daemon's config.json, and registers a native background service — systemd on Linux, launchd on macOS, the Service Control Manager on Windows, and rc.d on FreeBSD — that starts immediately and on every reboot. The install command shown on the wizard's Install step already includes this; copy and run it on the host.
install accepts the same connection and identity flags as the daemon itself, so you can also invoke it by hand. Get the invocation from the app rather than assembling it yourself — the wizard and the management modal build it against your server's own URL and the daemon's key.
Everything else — network, interfaces, ports — is read from config.json, so no secrets appear in the service definition or process arguments. Re-running install is idempotent, and a non-elevated invocation prints the exact sudo/administrator command to re-run. 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 that runs alongside the server. This daemon is managed as part of your Compose stack — it upgrades when you upgrade the server and needs no separate installation. Server setup provisions it and its API key for you, so there is nothing to configure by hand. For upgrading the integrated daemon along with your server, see Upgrading a Self-Hosted Server.
Upgrading
When an update is available, the daemon card in Discover > Scan > Daemons shows an Update button. Click it to see platform-specific upgrade steps: download the latest binary, then restart the service (systemctl restart / launchctl kickstart -k / sc.exe stop + start / service … restart). Configuration is preserved across upgrades.
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. The modal has two tabs: Details for the daemon record, and API Key for its key.
On the Details tab you can edit the maintainer, tags, and — for ServerPoll daemons — the URL the server dials. Network, polling mode, and name are shown read-only: they're set when the daemon is provisioned and define what the daemon is. A DaemonPoll daemon has no editable URL, because 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 either by reconfiguring the daemon from the modal or by editing config.json directly. Editing the file requires a service restart to take effect — sudo systemctl restart scanopy-daemon (Linux), sudo launchctl kickstart -k system/com.scanopy.daemon (macOS), sc.exe stop scanopy-daemon then sc.exe start scanopy-daemon (Windows), or sudo service scanopy-daemon restart (FreeBSD). For a foreground daemon, just restart the process.
Each daemon also reports its capabilities to the server: whether it has Docker or Podman socket access (for container discovery) and which subnets it has network interfaces on (for default scan targets). To update capabilities after changing the host's network configuration or Docker access, run a SelfReport discovery.
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 installed binary and log files. On a host running several daemons, target one with --name <selector> — the daemon's name, its slot, or its service id, all shown by scanopy-daemon list — or remove every one with --all. On Windows, run it from an elevated PowerShell.
uninstall reports what it did for every item it touched — removed, left in place, or not found — so you can see exactly what remains. It's idempotent: uninstalling a daemon that was never installed succeeds and tells you there was nothing to remove.
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.