Self-hosted service
karam-ajaj/atlas avatar
karam-ajaj/atlas

Atlas: Docker and Subnet Discovery Behind a React Graph

Open-source tool for network discovery, visualization, and monitoring. Built with Go, FastAPI, and React, supports Docker host scanning.

1,323 stars75 forksJavaScriptMIT

At a glance

What is it?
Atlas is an MIT-licensed, containerized scanner that walks Docker containers and local subnets, stores the results in SQLite, and renders them as interactive network graphs. It fits a homelab or small self-hosted fleet, but its host networking and Docker socket mount are the terms of the deal.
Who is it for?
Adopt Atlas if you run a self-hosted Docker host or small fleet and want a graph of containers, interfaces, MACs and open ports without standing up a full monitoring stack. Skip it if you cannot grant NET_RAW, NET_ADMIN and the Docker socket, or if you need agent-based collection across many remote subnets.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 72 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap Atlas fills between docker ps and a network diagram

Docker tells you what is running. It does not tell you which MAC address a container's second interface is using, or which of its ports is reachable from the subnet. Atlas exists to close that gap. The README describes three functions: scanning Docker containers on the host, scanning local and neighboring hosts on the subnet, and rendering the combined result in a dashboard. The Docker scan extracts IP addresses, MAC addresses, open ports, network names and OS type from image metadata, and the README states that multiple IPs and multiple MACs per container are supported because each network interface is tracked separately. That last detail is the interesting one. A container attached to two Docker networks is a common source of confusion, and treating interfaces as first-class rows rather than collapsing them into one address is a deliberate modeling choice. The audience is the homelab operator or small infrastructure team that already runs Docker and wants a visual inventory without deploying agents on every machine.

Three scan cadences and what each one touches

The scheduler is not a single loop. The README names three interval variables: FASTSCAN_INTERVAL, DOCKERSCAN_INTERVAL and DEEPSCAN_INTERVAL, defaulting to 3600, 3600 and 7200 seconds respectively. Fast scans and Docker scans run hourly by default; deep scans run every two hours. The naming implies a cost gradient, with the deep scan doing the more expensive probing, though the README does not spell out which techniques each tier uses. What it does say is that intervals can be changed at runtime through the Scripts Panel in the UI, not only through environment variables at container start. The scheduler starts automatically with the container and runs in the background. For a homelab this is reasonable: an hourly sweep of a /24 is cheap, and the two-hour deep pass keeps fingerprinting off the critical path. The trade-off is that you inherit three knobs to reason about, and the README does not document what happens if a scan overruns its interval.

Go CLI, FastAPI, NGINX and SQLite in one image

The stack is split by responsibility. A Go 1.22 CLI named atlas handles initdb, which creates the SQLite database with the required schema, and presumably the scanning work itself. A FastAPI backend exposes data and control endpoints. NGINX serves the React frontend and, per the README's endpoint examples, can also proxy the API under the same port. The README lists two paths to the API docs: http://localhost:ATLAS_API_PORT/api/docs when hitting the API port directly, and http://localhost:ATLAS_UI_PORT/api/docs based on the nginx configuration. That dual exposure is worth noting. If you publish only the UI port, the API is still reachable through the proxy, which matters for how you reason about authentication scope. The README does not describe the Go scanner's internals beyond the initdb subcommand, so the exact discovery mechanism for neighboring hosts is not documented in the supplied material. What is documented is the output shape: hosts with OS fingerprints, MACs and open ports, plus container records with per-interface detail, all persisted in SQLite and read back by the API.

The docker run line, flag by flag

Deployment is a single container. The README gives this command: docker run -d with --name atlas, --network=host, --cap-add=NET_RAW, --cap-add=NET_ADMIN, a bind mount of /var/run/docker.sock into the same path, and a set of -e variables. The environment variables are ATLAS_UI_PORT (default 8888), ATLAS_API_PORT (default 8889), ATLAS_ADMIN_USER (default admin), ATLAS_ADMIN_PASSWORD (default disabled), ATLAS_AUTH_TTL_SECONDS (default 86400), the three scan intervals, and SCAN_SUBNETS. SCAN_SUBNETS takes a comma-separated list such as "192.168.1.0/24,10.0.0.0/24"; if it is unset, Atlas auto-detects the local subnet. The README notes this allows scanning multiple networks including LAN and remote servers. Two flags deserve attention. NET_RAW is what enables raw-socket probing; NET_ADMIN is broader and grants interface and routing manipulation. Host networking means the container sees the host's interfaces directly, which is why auto-detection works, and also why port variables become the only way to avoid collisions with services already on the host.

Authentication is optional, and that default is the sharp edge

The README states plainly that Atlas authentication is optional and disabled by default. Setting ATLAS_ADMIN_PASSWORD enables it; the username defaults to admin. When enabled, the UI shows a login gate before rendering any data, and core endpoints (hosts, external, scripts, logs, scheduler, containers) require a bearer token. The auth endpoints are GET /api/auth/enabled, POST /api/auth/login, GET /api/auth/me and POST /api/auth/logout. The TTL variable controls session lifetime, defaulting to 86400 seconds. Consider what an unauthenticated instance exposes: a map of your network, open ports per host, container inventories, and a scripts panel that can change scan intervals and trigger scans. The live demo at atlasdemo.vnerd.nl uses the credentials admin / change-me, which is fine for a demo and unacceptable anywhere else. The single-user model is also a real limit. There are no roles, no per-endpoint scoping, and no audit trail described in the material. If two people need access, they share one credential.

Where Atlas is the wrong tool

The deployment requirements rule out a large class of environments. Granting NET_RAW and NET_ADMIN plus the Docker socket is close to root on the host, and managed container platforms, locked-down Kubernetes clusters and shared CI runners will not allow it. The Docker socket mount alone means anything that compromises the Atlas container can talk to the Docker daemon. If your policy forbids that, Atlas is not a candidate regardless of its features. The scanning model is also host-centric: Atlas discovers from the vantage point of the machine it runs on, using auto-detected or explicitly listed subnets. There is no agent described in the material, so covering several isolated network segments means running several instances and reconciling their databases yourself. And the persistence layer is SQLite with no clustering or replication mentioned, which caps this at single-node scale. Teams that need long-term metric retention, alerting rules or multi-tenant access control are looking at a different category of tool.

How it differs from Zabbix and Nagios

Zabbix and Nagios approach the same territory from the opposite direction. Both are agent-based or plugin-based monitoring systems: you install an agent or configure a check on each host you care about, and the server aggregates metrics and raises alerts against thresholds. Atlas inverts that. It runs on one host, probes outward with raw sockets, and reads Docker's own state through the socket, so containers appear without any per-container configuration. The output is an inventory and a topology graph rather than a time-series alerting pipeline. That difference cuts both ways. Atlas needs no agent rollout, which is why it suits a homelab, and it cannot see anything its single vantage point cannot reach or anything Docker does not report. Choosing between them is really choosing between discovery and monitoring. If your question is what is on my network right now, Atlas answers it. If your question is why did latency spike at 03:00, it does not.

Licence, upgrade cost and what to verify first

Atlas is MIT-licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is a permissive licence with no copyleft obligation on your own code, though this is a description of the licence text and not legal advice. On maintenance, the repository is not archived and the release history shows 3.3.4 in February 2026, 3.3.0 in October 2025 and 3.2.29 earlier that same month, with the last push in July 2026. The cadence suggests active but not constant development, and the patch-level numbering between 3.2.29 and 3.3.0 hints at incremental fixes rather than long-lived release branches. Upgrades are a container image swap plus whatever schema changes initdb applies to the SQLite file, so back up the database volume before pulling a new tag. The README does not document migration behavior, which is the thing to confirm before upgrading in place. Verify three things first: that SCAN_SUBNETS is set explicitly rather than relying on auto-detection, that ATLAS_ADMIN_PASSWORD is set, and that your host policy actually permits NET_RAW, NET_ADMIN and the Docker socket mount.

Editorial conclusion

Adopt Atlas if you run a self-hosted Docker host or small fleet and want a graph of containers, interfaces, MACs and open ports without standing up a full monitoring stack. Skip it if you cannot grant NET_RAW, NET_ADMIN and the Docker socket, or if you need agent-based collection across many remote subnets. Before deploying, verify that SCAN_SUBNETS covers exactly the ranges you intend to probe, and set ATLAS_ADMIN_PASSWORD, since authentication is disabled by default.

Official sources

  1. karam-ajaj/atlas on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Community notes

Community notes