{"id":31569061,"url":"https://github.com/karam-ajaj/atlas","last_synced_at":"2026-06-10T16:01:53.591Z","repository":{"id":293553507,"uuid":"984410363","full_name":"karam-ajaj/atlas","owner":"karam-ajaj","description":"Open-source tool for network discovery, visualization, and monitoring. Built with Go, FastAPI, and React, supports Docker host scanning.","archived":false,"fork":false,"pushed_at":"2025-09-21T22:10:00.000Z","size":36620,"stargazers_count":200,"open_issues_count":6,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-21T23:35:45.545Z","etag":null,"topics":["container","devops","devops-tools","docker","docker-monitoring","docker-swarm","fastapi","golang","homelab","host-discovery","infrastructure-automation","network-discovery","network-monitoring","network-visualization","networking","open-source","react","self-hosted"],"latest_commit_sha":null,"homepage":"https://atlasdemo.vnerd.nl","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/karam-ajaj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-05-15T22:18:05.000Z","updated_at":"2025-09-21T23:34:18.000Z","dependencies_parsed_at":"2025-09-21T23:34:42.806Z","dependency_job_id":null,"html_url":"https://github.com/karam-ajaj/atlas","commit_stats":null,"previous_names":["karam-ajaj/atlas"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/karam-ajaj/atlas","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karam-ajaj%2Fatlas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karam-ajaj%2Fatlas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karam-ajaj%2Fatlas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karam-ajaj%2Fatlas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/karam-ajaj","download_url":"https://codeload.github.com/karam-ajaj/atlas/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karam-ajaj%2Fatlas/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278444551,"owners_count":25987790,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["container","devops","devops-tools","docker","docker-monitoring","docker-swarm","fastapi","golang","homelab","host-discovery","infrastructure-automation","network-discovery","network-monitoring","network-visualization","networking","open-source","react","self-hosted"],"created_at":"2025-10-05T11:16:36.376Z","updated_at":"2026-06-10T16:01:53.580Z","avatar_url":"https://github.com/karam-ajaj.png","language":"Shell","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"\n# 🌐 Atlas - Network Infrastructure Visualizer (Go-powered)\n\n**Atlas** is a full-stack containerized tool to **scan**, **analyze**, and **visualize** network infrastructure dynamically. Built with Go, FastAPI, NGINX, and a custom React frontend, it provides automated scanning, storage, and rich dashboards for insight into your infrastructure.\n\n---\n\n## 🌍 Live Demo\n\n🔗 **URL:** https://atlasdemo.vnerd.nl/  \n👤 **Username:** `admin`  \n🔑 **Password:** `change-me`\n\n---\n## 🚀 What It Does\n\nAtlas performs three key functions:\n\n1. **Scans Docker Containers** running on the host to extract:\n   - IP addresses **(supports multiple IPs per container)**\n   - MAC addresses **(supports multiple MACs per container)**\n   - Open ports\n   - Network names\n   - OS type (from image metadata)\n   - **Each network interface is tracked separately**\n\n2. **Scans Local \u0026 Neighboring Hosts** on the subnet to:\n   - Detect reachable devices\n   - Retrieve OS fingerprints, MACs, and open ports\n   - Populate a full map of the infrastructure\n\n3. **Visualizes Data in Real-Time**:\n   - Serves an interactive HTML dashboard via Nginx\n   - Hosts a FastAPI backend for data access and control\n   - Uses a React frontend to render dynamic network graphs\n\n---\n\n## 🖼️ Screenshots\n\n### 🖥️ Desktop View\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=\"50%\"\u003e\n\u003ca href=\"screenshots/dashboard_big_c.png\" target=\"_blank\"\u003e\n\u003cimg src=\"screenshots/dashboard_big_c.png\" alt=\"Dashboard - Collapsed Layout\" style=\"border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);\" /\u003e\n\u003cp align=\"center\"\u003e\u003cem\u003eDashboard - Circular Layout\u003c/em\u003e\u003c/p\u003e\n\u003c/a\u003e\n\u003c/td\u003e\n\u003ctd width=\"50%\"\u003e\n\u003ca href=\"screenshots/dashboard_big_h.png\" target=\"_blank\"\u003e\n\u003cimg src=\"screenshots/dashboard_big_h.png\" alt=\"Dashboard - Horizontal Layout\" style=\"border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);\" /\u003e\n\u003cp align=\"center\"\u003e\u003cem\u003eDashboard - Hierarchical Layout\u003c/em\u003e\u003c/p\u003e\n\u003c/a\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd width=\"50%\"\u003e\n\u003ca href=\"screenshots/table_big.png\" target=\"_blank\"\u003e\n\u003cimg src=\"screenshots/table_big.png\" alt=\"Hosts Table View\" style=\"border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);\" /\u003e\n\u003cp align=\"center\"\u003e\u003cem\u003eHosts Table View\u003c/em\u003e\u003c/p\u003e\n\u003c/a\u003e\n\u003c/td\u003e\n\u003ctd width=\"50%\"\u003e\n\u003ca href=\"screenshots/logs_big.png\" target=\"_blank\"\u003e\n\u003cimg src=\"screenshots/logs_big.png\" alt=\"Logs Panel\" style=\"border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);\" /\u003e\n\u003cp align=\"center\"\u003e\u003cem\u003eLogs Panel\u003c/em\u003e\u003c/p\u003e\n\u003c/a\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n### 📱 Mobile View\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=\"25%\" align=\"center\"\u003e\n\u003ca href=\"screenshots/dashboard_small_c.png\" target=\"_blank\"\u003e\n\u003cimg src=\"screenshots/dashboard_small_c.png\" alt=\"Mobile Dashboard - Collapsed\" style=\"border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); max-width: 250px;\" /\u003e\n\u003cp align=\"center\"\u003e\u003cem\u003eDashboard - Collapsed\u003c/em\u003e\u003c/p\u003e\n\u003c/a\u003e\n\u003c/td\u003e\n\u003ctd width=\"25%\" align=\"center\"\u003e\n\u003ca href=\"screenshots/dashboard_small_h.png\" target=\"_blank\"\u003e\n\u003cimg src=\"screenshots/dashboard_small_h.png\" alt=\"Mobile Dashboard - Horizontal\" style=\"border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); max-width: 250px;\" /\u003e\n\u003cp align=\"center\"\u003e\u003cem\u003eDashboard - Horizontal\u003c/em\u003e\u003c/p\u003e\n\u003c/a\u003e\n\u003c/td\u003e\n\u003ctd width=\"25%\" align=\"center\"\u003e\n\u003ca href=\"screenshots/table_small.png\" target=\"_blank\"\u003e\n\u003cimg src=\"screenshots/table_small.png\" alt=\"Mobile Hosts Table\" style=\"border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); max-width: 250px;\" /\u003e\n\u003cp align=\"center\"\u003e\u003cem\u003eHosts Table\u003c/em\u003e\u003c/p\u003e\n\u003c/a\u003e\n\u003c/td\u003e\n\u003ctd width=\"25%\" align=\"center\"\u003e\n\u003ca href=\"screenshots/logs_small.png\" target=\"_blank\"\u003e\n\u003cimg src=\"screenshots/logs_small.png\" alt=\"Mobile Logs Panel\" style=\"border: 2px solid #ddd; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); max-width: 250px;\" /\u003e\n\u003cp align=\"center\"\u003e\u003cem\u003eLogs Panel\u003c/em\u003e\u003c/p\u003e\n\u003c/a\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003e 💡 **Tip:** Click on any screenshot to view the full-size image\n\n---\n\n## 🚀 Deployment (Docker)\n\nRun Atlas with optional port configuration:\n\n```bash\ndocker run -d \\\n  --name atlas \\\n  --network=host \\\n  --cap-add=NET_RAW \\\n  --cap-add=NET_ADMIN \\\n  -v /var/run/docker.sock:/var/run/docker.sock \\\n  -e ATLAS_UI_PORT='8884' \\\n  -e ATLAS_API_PORT='8885' \\\n  -e ATLAS_ADMIN_USER='admin' \\\n  -e ATLAS_ADMIN_PASSWORD='change-me' \\\n  -e ATLAS_AUTH_TTL_SECONDS='86400'\n  -e FASTSCAN_INTERVAL='3600' \\\n  -e DOCKERSCAN_INTERVAL='3600' \\\n  -e DEEPSCAN_INTERVAL='7200' \\\n  -e SCAN_SUBNETS=\"192.168.1.0/24,10.0.0.0/24\" \\\n  keinstien/atlas:{tag}\n```\n\n**Environment Variables:**\n- `ATLAS_UI_PORT` – Sets the port for the Atlas UI (Nginx). Default: `8888`.\n- `ATLAS_API_PORT` – Sets the port for the FastAPI backend. Default: `8889`.\n- `ATLAS_ADMIN_USER` – Admin username for login (single user). Default: `admin`.\n- `ATLAS_ADMIN_PASSWORD` – Enables UI/API authentication when set (required password for login). Default: `disabled`.\n- `ATLAS_AUTH_TTL_SECONDS` – Session lifetime in seconds. Default: `86400` (24h).\n- `FASTSCAN_INTERVAL` – Interval in seconds between fast scans. Default: `3600` (1 hour).\n- `DOCKERSCAN_INTERVAL` – Interval in seconds between Docker scans. Default: `3600` (1 hour).\n- `DEEPSCAN_INTERVAL` – Interval in seconds between deep scans. Default: `7200` (2 hours).\n- `SCAN_SUBNETS` – Comma-separated list of subnets to scan (e.g., \"192.168.1.0/24,10.0.0.0/24\"). If not set, Atlas will auto-detect the local subnet. This allows scanning multiple networks including LAN and remote servers.\n\nIf not set, defaults are used (UI: `8888`, API: `8889`, scan intervals as shown above).\n\nExample endpoints:\n- UI:                               `http://localhost:ATLAS_UI_PORT`\n- API (from exposed API port):      `http://localhost:ATLAS_API_PORT/api/docs`\n- API (based on nginx conf):        `http://localhost:ATLAS_UI_PORT/api/docs`\n\n### 🔐 Authentication\n\nAtlas authentication is optional and disabled by default.\n\n- **Enable auth:** set `ATLAS_ADMIN_PASSWORD` (and optionally `ATLAS_ADMIN_USER`).\n- **UI behavior:** when auth is enabled, the UI shows a login gate before any data is rendered.\n- **API behavior:** when auth is enabled, core endpoints (hosts, external, scripts, logs, scheduler, containers) require a token.\n\nRelevant auth endpoints:\n- `GET /api/auth/enabled` – returns whether auth is enabled\n- `POST /api/auth/login` – returns a bearer token\n- `GET /api/auth/me` – validates current token\n- `POST /api/auth/logout` – invalidates the current token\n\n**Scan Scheduling:**\nAtlas automatically runs scans at the configured intervals. You can:\n- Set initial intervals via environment variables (see above)\n- Change intervals dynamically through the Scripts Panel in the UI\n- Manually trigger scans via the UI or API at any time\n\nThe scheduler starts automatically when the container starts and runs scans in the background.\n\n---\n\n## ⚙️ How it Works\n\n### 🔹 Backend Architecture\n\n- **Go CLI (`atlas`)**\n  - Built using Go 1.22\n  - Handles:\n    - `initdb`: Creates SQLite DB with required schema\n    - `fastscan`: Fast host scan using ARP/Nmap\n    - `dockerscan`: Gathers Docker container info from `docker inspect`\n    - `deepscan`: Enriches data with port scans, OS info, etc.\n\n- **FastAPI Backend**\n  - Runs on `port 8889`\n  - Serves:\n    - `/api/hosts` – all discovered hosts (regular + Docker)\n    - `/api/external` – external IP and metadata\n\n- **NGINX**\n  - Serves frontend (React static build) on `port 8888`\n  - Proxies API requests (`/api/`) to FastAPI (`localhost:8889`)\n\n---\n\n## 📂 Project Structure\n\n**Source Code (Host Filesystem)**\n\n```\natlas/\n├── config/\n│   ├── atlas_go/        # Go source code (main.go, scan, db)\n│   ├── bin/             # Compiled Go binary (atlas)\n│   ├── db/              # SQLite file created on runtime\n│   ├── logs/            # Uvicorn logs\n│   ├── nginx/           # default.conf for port 8888\n│   └── scripts/         # startup shell scripts\n├── data/\n│   ├── html/            # Static files served by Nginx\n│   └── react-ui/        # Frontend source (React)\n├── Dockerfile\n├── LICENSE\n└── README.md\n```\n\n**Inside Container (/config)**\n```\n/config/\n├── bin/atlas             # Go binary entrypoint\n├── db/atlas.db           # Persistent SQLite3 DB\n├── logs/                 # Logs for FastAPI\n├── nginx/default.conf    # Nginx config\n└── scripts/atlas_check.sh # Entrypoint shell script\n\n```\n\n---\n\n## 🧪 React Frontend (Dev Instructions)\n\nThis is a new React-based UI.\n\n### 🛠️ Setup and Build\n\n```bash\ncd /swarm/data/atlas/react-ui\nnpm install\nnpm run build\n```\n\nThe built output will be in:\n```\n/swarm/data/atlas/react-ui/dist/\n```\n\nFor development CI/CD (for UI and backend and build a new docker version):\n```bash\n/swarm/github-repos/atlas/deploy.sh\n```\n\n\n## 🚀 CI/CD: Build and Publish a New Atlas Docker Image\n\nTo deploy a new version and upload it to Docker Hub, use the provided CI/CD script:\n\n1. Build and publish a new image:\n\n   ```bash\n   /swarm/github-repos/atlas/deploy.sh\n   ```\n\n   - The script will prompt you for a version tag (e.g. `v3.2`).\n   - It will build the React frontend, copy to NGINX, build the Docker image, and push **both** `keinstien/atlas:$VERSION` and `keinstien/atlas:latest` to Docker Hub.\n\n2. Why push both tags?\n\n   - **Version tag:** Allows you to pin deployments to a specific release (e.g. `keinstien/atlas:v3.2`).\n   - **Latest tag:** Users can always pull the most recent stable build via `docker pull keinstien/atlas:latest`.\n\n3. The script will also redeploy the running container with the new version.\n\n**Example output:**\n```shell\n🔄 Tagging Docker image as latest\n📤 Pushing Docker image to Docker Hub...\n✅ Deployment complete for version: v3.2\n```\n\n\u003e **Note:** Make sure you are logged in to Docker Hub (`docker login`) before running the script.\n\n\n---\n\n## 🌍 URLs\n\n- **Swagger API docs:**\n  - `🌍 http://localhost:8888/api/docs` (Host Data API endpoint)\n\n- **Frontend UI:**\n  - `🖥️ UI\thttp://localhost:8888/` (main dashboard)\n  - `📊 http://localhost:8888/hosts.html` (Hosts Table)\n  - `🧪 http://localhost:8888/visuals/vis.js_node_legends.html` (legacy test UI)\n\n\u003e Default exposed port is: `8888`\n\n### 📡 Scheduler API Endpoints\n\nNew scheduler management endpoints:\n\n- `GET /api/scheduler/intervals` - Get current scan intervals for all scan types\n- `PUT /api/scheduler/intervals/{scan_type}` - Update interval for a specific scan type (fastscan, dockerscan, or deepscan)\n- `GET /api/scheduler/status` - Get scheduler status and current intervals\n\nExample:\n```bash\n# Get current intervals\ncurl http://localhost:8888/api/scheduler/intervals\n\n# Update fastscan interval to 30 minutes (1800 seconds)\ncurl -X PUT http://localhost:8888/api/scheduler/intervals/fastscan \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"interval\": 1800}'\n\n# Check scheduler status\ncurl http://localhost:8888/api/scheduler/status\n```\n\n---\n\n## ✅ Features\n\n- [x] **Multi-interface scanning** - Automatically detects and scans all physical network interfaces on the host\n- [x] Fast network scans (ping/ARP)\n- [x] **Multiple subnet scanning** - Scan your LAN, remote servers, and multiple networks simultaneously via SCAN_SUBNETS environment variable\n- [x] Docker container inspection with **multi-network support**\n- [x] **Multiple IPs and MACs per container** - Containers on multiple networks show all interfaces\n- [x] **Interface-aware host tracking** - Same host on multiple interfaces appears separately with interface labels\n- [x] External IP discovery\n- [x] Deep port scans with OS enrichment\n- [x] React-based dynamic frontend\n- [x] NGINX + FastAPI routing\n- [x] SQLite persistence\n- [x] **Scheduled auto scans with configurable intervals** - Configure via environment variables or UI\n- [x] **Dynamic interval management** - Change scan intervals without restarting the container\n\n---\n\n## 📌 Dev Tips\n\nTo edit Go logic:\n- Main binary: `internal/scan/`\n- Commands exposed via: `main.go`\n\nTo edit API:\n- Python FastAPI app: `scripts/app.py`\n\nTo edit UI:\n- Modify React app under `/react-ui`\n- Rebuild and copy static files to `/html`\n- _automated deplolyment and publish to dockerhub using the script deploy.sh_\n---\n\n## ⚙️ Automation Notes\n- Atlas runs automatically on container start.\n\n- All Go scan tasks run sequentially:\n   - `initdb → fastscan → deepscan → dockerscan`\n\n- Scheduled scans are run every 30 minutes via Go timers.\n\n- No cron dependency required inside the container.\n\n- Scans can also be manually triggered via the UI using API post request.\n---\n## 👨‍💻 Author\n\n**Karam Ajaj**  \nInfrastructure \u0026 Automation Engineer  \n[https://github.com/karam-ajaj](https://github.com/karam-ajaj)\n\n---\n\n## 📝 License\n\nMIT License — free for personal or commercial use.\n\n---\n\n## 📚 Documentation\n\n- [Multi-Interface Support](MULTI_INTERFACE_SUPPORT.md) - Detailed guide on the multi-interface scanning feature\n- [Migration Guide](MIGRATION_GUIDE.md) - Guide for migrating from bash scripts to Go implementation\n\n## 🤝 Contributing\n\nSuggestions, bug reports, and pull requests are welcome!\n\n## Star History\n\n[![Star History Chart](https://api.star-history.com/svg?repos=karam-ajaj/atlas\u0026type=date\u0026legend=top-left)](https://www.star-history.com/#karam-ajaj/atlas\u0026type=date\u0026legend=top-left)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaram-ajaj%2Fatlas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkaram-ajaj%2Fatlas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaram-ajaj%2Fatlas/lists"}