Website · Live demo · Quick start · Features · How it works · Security · Contributing
You SSH into a server and start piecing things together — docker ps, kubectl get pods, ss -tlnp, systemctl list-units, df -h... ten commands later you still have no real picture of what's running and how it all connects.
InfraCanvas replaces that ritual with one command. It automatically discovers every container, pod, service, volume and network on the host — plus systemd services and processes on plain VMs — and serves a live, interactive topology map in your browser. Nodes are green when healthy, red when not. You can open a terminal inside any container, tail logs, restart a service, or scale a deployment, all without leaving the page.
It is not another list. It is a map — what runs where, what talks to what, and what's broken — in one glance.
On any Linux VM (cloud or bare metal):
curl -fsSL https://github.com/bytestrix/InfraCanvas/releases/latest/download/install.sh | bashIn under 30 seconds:
✓ InfraCanvas installed and running
Open in your browser:
https://shy-pine-2f1a.trycloudflare.com/?token=a8f3e2b1c9d4f02e
Auth token: a8f3e2b1c9d4f02e (saved in /etc/infracanvas/config.env)
Open the URL — your infrastructure is live on the canvas. No Docker required. No firewall changes. No signup. No config files.
The URL is a free Cloudflare quick-tunnel — outbound-only, works from anywhere, no inbound port needed.
Install options
# Custom port (default 7777) — only matters with --no-tunnel
curl -fsSL .../install.sh | bash -s -- --port 8888
# Skip Cloudflare tunnel; bind 0.0.0.0:7777 directly
curl -fsSL .../install.sh | bash -s -- --no-tunnel
# Bind 127.0.0.1 only; reach via SSH tunnel (implies --no-tunnel)
curl -fsSL .../install.sh | bash -s -- --private
# Read-only: viewers can look, not touch — public demos and dashboards on a TV
curl -fsSL .../install.sh | bash -s -- --read-only
# Pin a specific version
curl -fsSL .../install.sh | bash -s -- --version v0.12.1Multiple VMs
Each VM is independent. Install on each one, open the printed URL for each in a separate tab. The binary is intentionally one-VM-per-dashboard.
Run on your laptop
Build from source (see Building from source), then:
infracanvas serve
# → https://*.trycloudflare.com/?token=… (or --no-tunnel for http://localhost:7777)You'll see your laptop's Docker containers and Kubernetes context on the canvas.
Every container, pod, service, volume and network drawn as connected nodes with edges showing what talks to what. Not a list — a map. Updates every 30 seconds, diff-only.
Plain VMs running nginx, postgres, node via systemd or PM2 get real workload nodes on the canvas. Listening ports and established connections are mapped from /proc/net/tcp — so you get real CONNECTS_TO edges (e.g. next-server → postgres :5432) without any config.
Containers managed by LXD or Incus are auto-discovered from the local socket and drawn on the canvas alongside Docker and Kubernetes — name, status, memory, and network, no config. (Discovery/visualization today; terminal & actions for LXC/LXD are on the roadmap.)
- Container terminal — full interactive shell inside any container
- VM shell — host PTY, no SSH needed
- Logs — tail any container, pod, or systemd service with one click, color-coded
- Actions — restart, stop, start, scale, rolling-restart, update image, service start/stop, process kill — all from the node panel
Green / amber / red from real container state, pod phase, and zombie process detection. An alert banner appears automatically when something breaks.
Env vars (secrets auto-masked), port mappings, volume mounts, image details, service unit, main PID, restart count, established connections.
One static Go binary with the dashboard embedded. Works with Docker, Kubernetes, plain systemd services, PM2 — none of them required.
Binds localhost. Outbound-only Cloudflare tunnel. Random per-install auth token. Secret redaction before data leaves the discovery layer. Runs as your user, not root. Optional --read-only mode for public dashboards.
┌─────────────────────────────────────────┐
│ your-vm │
│ │
│ ┌────────────────────────────────┐ │
│ │ infracanvas (single binary) │ │
│ │ ├── discovery agent │ │
│ │ ├── WebSocket relay │ │
│ │ └── embedded dashboard UI │ │
│ └────────────────────────────────┘ │
│ ▲ 127.0.0.1:7777 │
│ │ │
│ ┌────────┴───────┐ │
│ │ cloudflared │ outbound only │
│ └────────┬───────┘ │
└────────────┼────────────────────────────┘
│ Cloudflare quick-tunnel
▼
┌──────────┐
│ browser │ → https://xyz.trycloudflare.com
└──────────┘
One binary, one URL. The dashboard, relay and agent all run in the same process on the machine you're inspecting. A bundled cloudflared opens an outbound-only tunnel so you get a public HTTPS URL with no inbound firewall rule. Your browser is just a client.
The default install uses a Cloudflare quick-tunnel for zero-config HTTPS. If you want to use your own domain and reverse proxy instead, pass --no-tunnel:
curl -fsSL https://github.com/bytestrix/InfraCanvas/releases/latest/download/install.sh | bash -s -- --no-tunnel
# Binds 0.0.0.0:7777 — no cloudflared process startedThen point your reverse proxy at 127.0.0.1:7777.
Nginx + Let's Encrypt
server {
listen 80;
server_name infra.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name infra.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/infra.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/infra.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:7777;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 300s;
}
}Get a cert: sudo certbot --nginx -d infra.yourdomain.com
Caddy (auto-HTTPS, simplest option)
infra.yourdomain.com {
reverse_proxy localhost:7777
}Caddy handles TLS automatically. No certbot needed.
SSH tunnel (no domain needed)
Keep the server private (--private binds 127.0.0.1 only), then forward to your laptop:
# On your laptop:
ssh -L 7777:127.0.0.1:7777 user@your-server
# Open: http://localhost:7777/?token=<your-token>No public exposure, no domain, no TLS setup.
The exposed URL. Default mode binds 127.0.0.1:7777 and exposes it through a Cloudflare quick-tunnel — outbound-only from your VM, HTTPS-terminated at Cloudflare's edge. Pass --no-tunnel to bind 0.0.0.0 directly, or --private to bind 127.0.0.1 only and reach it via SSH tunnel.
The auth token. Every install generates a random 24-character token saved to /etc/infracanvas/config.env. The dashboard requires it on first visit (?token=…); after that it's in an HTTP-only cookie. Without the token, every request returns 401. Treat the URL+token like an SSH key for the box.
Read-only mode. Pass --read-only to turn the dashboard into a viewer — the relay rejects every action and terminal request server-side. Topology and logs still work. Use this for public demos or a wall-mounted status screen.
Secret redaction. Env vars whose names contain SECRET, TOKEN, KEY, PASSWORD, CREDENTIAL, AUTH, or PASSWD are replaced with [REDACTED] before they leave the discovery layer.
Runs as you, not root. The systemd unit runs as $SUDO_USER. The agent inherits your ~/.kube/config and docker group membership — no privilege escalation beyond what you already have.
See SECURITY.md for the vulnerability disclosure policy.
sudo systemctl status infracanvas
sudo systemctl restart infracanvas
sudo systemctl stop infracanvas
sudo journalctl -u infracanvas -fConfig in /etc/infracanvas/config.env:
INFRACANVAS_UI_TOKEN=a8f3e2b1c9d4f02e
INFRACANVAS_PORT=7777
INFRACANVAS_TUNNEL=true
INFRACANVAS_PRIVATE=false
INFRACANVAS_READONLY=falseEdit, then sudo systemctl restart infracanvas.
Uninstall
curl -fsSL https://github.com/bytestrix/InfraCanvas/releases/latest/download/uninstall.sh | sudo bashRemoves: binary, systemd unit, /etc/infracanvas/, and the cached cloudflared binary (~30 MB). Or run locally: sudo ./uninstall-agent.sh
Requirements: Go 1.21+, Node.js 20+
git clone https://github.com/bytestrix/InfraCanvas.git
cd InfraCanvas
make all # build dashboard + binary (with embedded UI)
./bin/infracanvas serve # → http://localhost:7777/?token=…Make targets
make build-frontend # Next.js static export → pkg/webui/dist/
make build # binary with embedded UI (requires dist/)
make build-stub # binary with placeholder UI — fast, for backend iteration
make release # cross-compile linux/darwin × amd64/arm64 → bin/release/
make test # Go tests
make clean # remove bin/ and embedded dashboardProject layout
InfraCanvas/
├── cmd/infracanvas/cmd/
│ ├── serve.go # `infracanvas serve` — boots relay + UI + agent
│ ├── start.go # `infracanvas start` — agent-only mode
│ ├── discover.go # one-shot CLI discovery
│ └── …
├── pkg/
│ ├── agent/ # WebSocket agent: discover, diff, exec, actions
│ ├── server/ # relay: WebSocket broker, sessions, auth, static UI
│ ├── webui/ # embedded dashboard (build-tagged)
│ ├── actions/ # Docker / K8s / Host action runners
│ ├── discovery/ # docker, host, kubernetes
│ ├── orchestrator/ # combines discovery sources into one snapshot
│ ├── output/ # graph builder
│ ├── relationships/ # edges between entities
│ ├── health/ # health status calculation
│ └── redactor/ # strips sensitive env vars
├── frontend/
│ ├── app/page.tsx # single-VM dashboard, auto-connects on mount
│ ├── components/canvas/ # ReactFlow canvas, node detail panel, terminal, logs
│ ├── lib/wsManager.ts # WS client
│ └── store/vmStore.ts # Zustand state
├── install-agent.sh
└── uninstall-agent.sh
See ARCHITECTURE.md for a deeper dive.
Contributions welcome. See CONTRIBUTING.md. Open an issue before a large PR. make test and make lint must pass, plus cd frontend && npm run lint.
New here? Start with good first issue.
GNU Affero General Public License v3.0 — see LICENSE.
- Free for any personal or internal company use
- Fork, modify, redistribute — keep changes open source
- If you run this as a paid cloud service for customers, your modifications must be open source too
Built by Bytestrix


