Quick start
A working install in about ten minutes
Edit this pageOn this page
A working Loomscope — control plane, database, worker and one scanning daemon — in about ten minutes. You need Docker and Docker Compose, and a network you are authorised to scan.
For a production install read Docker Compose and Configuration instead; this page takes the shortest honest path, and says where it cuts a corner.
1. Get the repository
git clone https://github.com/bendaamerahmed/loomscope.git
cd loomscope
cp .env.example .env2. Generate the secrets
Four values in .env are marked REQUIRED. The compose file references them
with the ${VAR:?} form, so compose aborts rather than starting with a
blank value — deliberately, because that is what stops a half-configured
install from coming up looking healthy.
openssl rand -hex 32 # BETTER_AUTH_SECRET — signs sessions
openssl rand -base64 32 # LOOMSCOPE_KMS_KEY — encrypts stored credentials
openssl rand -hex 24 # POSTGRES_PASSWORD — database passwordUse -hex for POSTGRES_PASSWORD, not -base64. That value ends up inside
DATABASE_URL, and base64 output contains / and + about half the time,
which makes the connection string an invalid URL that the driver refuses
outright.
LOOMSCOPE_KMS_KEYis the one to guard. It encrypts every credential Loomscope stores. Lose it and those are unrecoverable; leak it and treat them all as compromised. Keep a copy somewhere that is not the server.
The fourth, LOOMSCOPE_DAEMON_API_KEY, does not exist yet — you mint it in
step 4.
3. Start the database and control plane
docker compose -f infra/docker-compose.yml up -d postgres serverMigrations are never applied automatically, in any environment. With more than one control-plane replica, automatic migration means every replica racing to alter the same schema at boot. Apply them yourself:
docker compose -f infra/docker-compose.yml run --rm server node --experimental-strip-types apps/server/server/db/migrate.tsThe runner records each file in a __migrations table and skips what is
already applied, so re-running it is safe.
4. Create the organisation and enrol a daemon
Open http://localhost:3000. A deployment with no organisation sends you to Set up Loomscope, which creates the organisation and its first account, then closes itself — the page cannot be reached again once an organisation exists, so it is not a standing door into a running deployment.
Sign in, then go to Settings → Daemons and enrol one. The key is shown once, like an invitation link: only its hash is stored, so a lost key is replaced rather than recovered.
Copy it into .env:
LOOMSCOPE_DAEMON_API_KEY=lsk_...
LOOMSCOPE_DAEMON_NAME=defaultThen start the scanner and the job worker:
docker compose -f infra/docker-compose.yml up -d daemon worker5. Add a network
Nothing is scanned until a network exists — Loomscope never probes a range you have not declared. Go to Networks → Add network and enter a CIDR, IPv4 or IPv6. Start with one small range.
A /24 completes a cold scan in under 30 seconds on a normal network. Open Hosts; results appear as they arrive and the page updates live over SSE.
If nothing appears
Two causes account for almost all of it.
The daemon cannot send an ICMP echo. Check for the fallback warning:
docker logs loomscope-daemon | grep "falling back to TCP"Without that one privileged operation the sweep degrades to TCP probes on 80, 443 and 22 — which finds web servers and misses printers, cameras and anything else that is up but serving nothing. Deploying daemons explains both supported ways to grant it.
A firewall is dropping the probes, or the daemon has no layer-2 reachability to the range. A host that answers nothing at all will not be discovered by active scanning; that is what SNMP, ARP-table collection and flow data are for.
What this quick start skipped
| Skipped | Why it matters | Where it is covered |
|---|---|---|
| TLS termination | Port 3000 is cleartext. Fine on a laptop, wrong for anything else | TLS and reverse proxy |
| Resource limits | The compose file sets none, so a runaway scan can consume the host | Scaling |
| Backups | The database and the encryption key have to survive together | Backup and restore |
| Single sign-on | Local accounts suit one team, not a directory that owns the user list | Single sign-on |
| An offline CVE mirror | Without one, vulnerability matching needs internet access | Air-gapped installation |