{"id":49227700,"url":"https://github.com/rifkyputra/postlab","last_synced_at":"2026-06-27T22:00:26.072Z","repository":{"id":310312640,"uuid":"1039394256","full_name":"rifkyputra/postlab","owner":"rifkyputra","description":"selfhost a homelab","archived":false,"fork":false,"pushed_at":"2026-06-26T09:00:31.000Z","size":42724,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-26T11:03:19.854Z","etag":null,"topics":["homelab","postgres","server","ubuntu-server"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rifkyputra.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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-08-17T05:59:33.000Z","updated_at":"2026-06-26T09:00:39.000Z","dependencies_parsed_at":"2025-08-17T09:15:35.212Z","dependency_job_id":"1a7bf0ae-86ea-473b-9065-4794aab57d2a","html_url":"https://github.com/rifkyputra/postlab","commit_stats":null,"previous_names":["rifkyputra/homelab","rifkyputra/uwuhomelab","rifkyputra/postlab"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/rifkyputra/postlab","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rifkyputra%2Fpostlab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rifkyputra%2Fpostlab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rifkyputra%2Fpostlab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rifkyputra%2Fpostlab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rifkyputra","download_url":"https://codeload.github.com/rifkyputra/postlab/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rifkyputra%2Fpostlab/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34869004,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-27T02:00:06.362Z","response_time":126,"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":["homelab","postgres","server","ubuntu-server"],"created_at":"2026-04-24T09:31:09.031Z","updated_at":"2026-06-27T22:00:26.055Z","avatar_url":"https://github.com/rifkyputra.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\u003cpre\u003e\n██████╗  ██████╗ ███████╗████████╗██╗      █████╗ ██████╗ \n██╔══██╗██╔═══██╗██╔════╝╚══██╔══╝██║     ██╔══██╗██╔══██╗\n██████╔╝██║   ██║███████╗   ██║   ██║     ███████║██████╔╝\n██╔═══╝ ██║   ██║╚════██║   ██║   ██║     ██╔══██║██╔══██╗\n██║     ╚██████╔╝███████║   ██║   ███████╗██║  ██║██████╔╝\n╚═╝      ╚═════╝ ╚══════╝   ╚═╝   ╚══════╝╚═╝  ╚═╝╚═════╝ \n\u003c/pre\u003e\n\n  \u003cp\u003e\n    \u003cb\u003eInteractive bare metal server manager — runs directly on the machine it manages.\u003c/b\u003e\n  \u003c/p\u003e\n\n  \u003cp\u003e\n    \u003cimg src=\"https://img.shields.io/badge/version-0.3.0-blue.svg\" alt=\"Version 0.3.0\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/license-Apache--2.0-green.svg\" alt=\"License Apache-2.0\"\u003e\n    \u003cimg src=\"https://github.com/rifkyputra/postlab/actions/workflows/build.yml/badge.svg\" alt=\"Build Status\"\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\nSingle binary. Low memory. Cross-platform (Linux + macOS).\n\n\u003e [!IMPORTANT]  \n\u003e **Postlab must run as root** to manage packages, services, and system configuration files.\n\n---\n\n## Demo\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"demo.gif\" alt=\"Postlab TUI demo — touring the Dashboard, Packages, Security, Networking, Docker, and Agent screens\" width=\"900\"\u003e\n\u003c/div\u003e\n\n\u003e Regenerate the GIF with [`vhs`](https://github.com/charmbracelet/vhs): `vhs demo.tape`.\n\n---\n\n## Features\n\n| Screen | Tabs / Sub-features | What it does |\n| ------ | ------------------- | ------------ |\n| **1. Dashboard** | Overview, Processes, Resources | Live hostname, OS, uptime, CPU cores, memory, disk gauges, and performance history. Process list with sort and kill. |\n| **2. Packages** | Installed, Search, Quick Install, Queue, Updates | Install / remove / upgrade packages; curated quick-install list; background operation queue; view available upgrades with version deltas and security flagging. |\n| **3. Security** | Findings, Firewall, Ports, SSH, Fail2Ban | SSH/ASLR audits with one-click fixes; UFW / firewalld / pf management; external port checker; authorized_keys manager; Fail2Ban list / ban / unban. |\n| **4. Networking** | Gateway, Tunnel, Tailscale | **Gateway:** Caddy installation and route management (domain → port) with automatic TLS. **Tunnel:** Cloudflare tunnel creation, route management, and ingress configuration. **Tailscale:** Install Tailscale, view VPN status and peers, bring up/down the connection. |\n| **5. Docker** | Containers, Images, Compose, Workloads, Managed | Manage Docker or Podman lifecycle, view image sizes, control Compose stacks, host-managed workloads, and one-click dev services (PostgreSQL, Redis, RabbitMQ, etc.). |\n| **6. wasmCloud** | Hosts, Components, Apps, Inspector | Manage wasmCloud lattices, host nodes, components, and applications. NATS backbone health and interactive inspector. |\n| **7. Agent** | Chat, Tools, Tasks, Status, Sessions, Config, Auth, Skills, Library, Logs | Interactive chat with pi agent; tool execution log; background task scheduler; install/update management; session browser; config/auth viewer; skill library with one-click install; live log tail. |\n| **8. System** | Ghosts, Janitor, Services, Users, Swap, Storage | Ghost process hunter; package-cache cleanup; systemd / launchd service control; Unix user CRUD and sudoers; swap file creation, resize, and enable/disable; filesystem browser with mount/unmount, physical disk SMART health, and /etc/fstab viewer. |\n| **9. Projects** | Projects, New, Clone, Settings | Browse local projects by last modified time; scaffold a new app via create-better-t-stack; clone a GitHub repo by shorthand or URL; configure the projects directory. |\n\nAll operations are **non-blocking** — the TUI stays responsive while background tasks (like package installations) run.\nEvery destructive change to config files creates a timestamped `.bak` backup first.\n\n### Docker / Workloads Disclaimers\n\n\u003e [!WARNING]\n\u003e The `Workloads` tab is a **system-level** feature. In v1 it is available only on **Linux hosts with `systemd`** and is intentionally unavailable on macOS or non-`systemd` environments.\n\n\u003e [!IMPORTANT]\n\u003e Postlab manages only **Postlab-owned canonical workload files** in the `Workloads` tab. It does **not** import, rewrite, or assume ownership of arbitrary existing Quadlet files, Compose projects, or hand-written systemd units.\n\n\u003e [!NOTE]\n\u003e Backend behavior is engine-specific by design:\n\u003e - **Podman** workloads are rendered as Quadlet `.container` units.\n\u003e - **Docker** workloads are rendered as a generated single-service `compose.yml` plus a generated `systemd` unit.\n\u003e - Existing ad-hoc Compose stacks should continue to be managed through the regular `Compose` tab, not `Workloads`.\n\u003e - The **Managed** tab provides curated one-click dev containers (PostgreSQL, Redis, MySQL, MongoDB, Elasticsearch, MinIO, MailHog, RabbitMQ) separate from Workloads.\n\n\u003e [!CAUTION]\n\u003e Workloads in v1 are **single-service only**. They are meant for durable host-managed services, not multi-service application graphs, cluster scheduling, or generic orchestration import/export.\n\n---\n\n## Quick Start\n\n### Installation\n\n**One-liner (Linux x86_64 / Linux arm64 / macOS arm64):**\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/rifkyputra/postlab/main/install.sh | bash\n```\n\nThe script detects your OS and architecture, downloads the matching binary from the latest [GitHub release](https://github.com/rifkyputra/postlab/releases), and installs it to `/usr/local/bin/postlab`. Running it again upgrades an existing installation.\n\n**Custom install path:**\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/rifkyputra/postlab/main/install.sh | DEST=~/.local/bin/postlab bash\n```\n\n**Pin a specific version:**\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/rifkyputra/postlab/main/install.sh | VERSION=v0.3.0 bash\n```\n\n**Build from source:**\n\n```bash\ngit clone https://github.com/rifkyputra/postlab.git\ncd postlab\nmake install   # builds release binary → /usr/local/bin/postlab\n```\n\n### Usage\n\n```bash\n# Launch interactive TUI (default)\nsudo postlab\n\n# One-shot commands (no TUI)\nsudo postlab info                       # System summary\nsudo postlab list                       # Installed packages\nsudo postlab system info                # OS, kernel, CPU, memory, uptime\nsudo postlab system cpu                 # Per-core CPU percentages\nsudo postlab system mem                 # Memory usage\nsudo postlab system disks               # Disk usage by mount point\nsudo postlab system net                 # Network RX/TX bytes\nsudo postlab system swap status         # Swap status and entries\nsudo postlab system swap create PATH M  # Create swap file (size in MiB)\nsudo postlab system swap delete PATH    # Remove swap file\nsudo postlab packages list              # Installed packages\nsudo postlab packages search QUERY      # Search package index\nsudo postlab packages install NAME      # Install a package\nsudo postlab packages remove NAME       # Remove a package\nsudo postlab packages upgrade           # Upgrade all packages\nsudo postlab packages cache-clean       # Clean package caches\nsudo postlab packages list-upgradable   # Available updates with security flags\nsudo postlab processes list             # Running processes (sort: -s cpu|mem|pid|name)\nsudo postlab processes kill PID         # Kill process (SIGTERM)\nsudo postlab processes kill PID -f      # Kill process (SIGKILL)\nsudo postlab services list              # Systemd services\nsudo postlab services start NAME        # Start a service\nsudo postlab services stop NAME         # Stop a service\nsudo postlab services restart NAME      # Restart a service\nsudo postlab services enable NAME       # Enable at boot\nsudo postlab services disable NAME      # Disable at boot\nsudo postlab storage list               # Filesystems + physical disks (SMART)\n\n# Custom SQLite database path (default: ~/.postlab/data.db)\nsudo postlab --database /var/lib/postlab/data.db\n```\n\n---\n\n## Keybindings\n\n### Navigation\n\n| Key | Action |\n| --- | ------ |\n| `1`–`9` | Switch screens |\n| `a` | Open Agent overlay (global) |\n| `s` | Jump to System (global, except on System screen) |\n| `Tab` / `Shift+Tab` | Next / previous screen |\n| `H` / `L` or `←` `→` | Switch tabs within a screen |\n| `↑` `↓` | Navigate lists or tables |\n| `Enter` | Confirm / execute / drill-down |\n| `Esc` | Clear filter / cancel input / return focus |\n| `q` | Quit |\n\n### Actions\n\n| Key | Context | Action |\n| --- | ------- | ------ |\n| `Space` | Lists | Toggle selection |\n| `r` / `R` | Most screens | Refresh current data |\n| `/` | Packages, Services, Agent Config | Search / filter |\n| `Esc` | Search/filter mode | Clear filter |\n| **Dashboard → Processes** |||\n| `c` / `m` / `p` | Process list | Sort by CPU / memory / PID |\n| `k` | Process list | Kill selected process (with confirm) |\n| **Packages** |||\n| `d` | Installed tab | Remove selected package(s) |\n| `i` | Search tab | Install selected package(s) |\n| `u` | Updates tab | Install selected update(s) |\n| `U` | Updates tab | Upgrade all packages |\n| **Security → Findings** |||\n| `s` | Findings tab | Run security scan |\n| `Enter` | Findings tab | Apply selected fix (with confirm) |\n| **Security → Firewall** |||\n| `a` | Firewall tab | Add new firewall rule |\n| `D` | Firewall tab | Delete selected rule |\n| **Security → SSH** |||\n| `g` | SSH tab | Generate new key pair |\n| **Security → Fail2Ban** |||\n| `f` | Jailed list | Forgive (unban) selected IP |\n| `b` | Jailed list | Banish (permanent block) selected IP |\n| **Networking → Gateway** |||\n| `a` | Gateway tab | Add route (domain → port) |\n| `D` | Gateway tab | Delete selected route |\n| `i` | Gateway tab | Install Caddy |\n| **Networking → Tunnel** |||\n| `a` | Tunnel tab | Create new tunnel |\n| `d` | Tunnel tab | Add domain to selected tunnel config |\n| `D` | Ingress panel | Delete selected ingress entry |\n| `e` | Ingress panel | Edit selected ingress service |\n| `f` | Tunnel tab | Toggle focus between Tunnels/Ingress |\n| `s` | Tunnel tab | Install cloudflared system service |\n| `c` | Tunnel tab | Refresh config + service status |\n| `i` | Tunnel tab | Install cloudflared |\n| `Enter` | Tunnel list | Select active tunnel (shows config + status) |\n| **Networking → Tailscale** |||\n| `i` | Tailscale tab | Install Tailscale |\n| `u` | Tailscale tab | Bring Tailscale up |\n| `d` | Tailscale tab | Take Tailscale down |\n| **Docker** |||\n| `s` | Containers tab | Start selected container |\n| `k` | Containers tab | Stop selected container (with confirm) |\n| `D` | Containers / Images | Remove container or image (with confirm) |\n| **wasmCloud** |||\n| `i` | wasmCloud tab | Install wash CLI |\n| `Enter` | Inspector | Inspect component (paste WIT path) |\n| **System → Ghosts** |||\n| `k` | Ghost list | Kill selected ghost process |\n| `r` | Ghost list | Re-scan for ghost processes |\n| **System → Services** |||\n| `s` / `k` / `r` | Service list | Start / stop / restart selected unit |\n| `e` / `d` | Service list | Enable / disable selected unit |\n| `c` | Janitor tab | Clean package manager caches |\n| **Projects** |||\n| `p` | Projects tab | git pull in selected project |\n| `c` | Clone tab | Clone (after entering repo URL) |\n| `s` | New tab | Open stack configurator popup |\n\n---\n\n## Pi Agent Integration\n\nThe **Agent** screen manages pi agent directly from Postlab:\n\n- Install and update pi agent from the Status tab\n- Chat interactively with pi agent and watch tool executions in real time\n- Schedule background agent jobs with configurable intervals (30m–24h)\n- Browse past sessions, view config/auth, and manage installed skills\n- Install skills from the curated Library with a single keypress\n- Tail the most recent session log\n\nPostlab shells out to the pi agent CLI via a JSONL-over-stdin/stdout RPC protocol — it does not embed pi agent source code. The agent process is spawned under the original user's UID/GID (via `$SUDO_UID`/`$SUDO_GID`) so it never runs as root.\n\n---\n\n## Architecture\n\nPostlab is built with a clean separation between the core logic and the TUI. The `core/` layer can be used independently (e.g., by an API or a future web interface).\n\n\u003e 📖 **TUI layout \u0026 mouse capture** — see [`docs/tui.md`](docs/tui.md) for screen layout, tab bar positions, and mouse click dispatch.\n\u003e 📖 **Full architecture** — see [`docs/architecture.md`](docs/architecture.md) for platform detection, data flow, background tasks, and design decisions.\n\n```\ncli/src/\n├── main.rs                  # clap entry: 8 subcommands + TUI (default)\n├── core/\n│   ├── platform.rs          # Platform { system, packages, processes, ... }\n│   │                        # detect() — auto-selects right impls at runtime\n│   ├── models.rs            # Shared data types (30+ structs/enums)\n│   ├── system/              # SystemInfo trait + sysinfo impl (swap, fstab)\n│   ├── packages/            # PackageManager trait + apt / dnf / pacman / brew\n│   ├── processes/           # ProcessManager trait + sysinfo impl\n│   ├── security/            # SecurityAuditor trait + SSH/ASLR/firewall checks\n│   ├── firewall/            # FirewallManager trait + ufw / firewalld / pf\n│   ├── portcheck/           # External port reachability checker (portchecker.co)\n│   ├── ssh/                 # SshKeyManager trait + authorized_keys / ssh-keygen\n│   ├── services/            # ServiceManager trait + systemd / launchd\n│   ├── users/               # Unix user CRUD + group management\n│   ├── storage/             # lsblk + SMART health, mount/umount, fstab viewer\n│   ├── docker/              # DockerManager trait + docker / podman CLI\n│   ├── workloads/           # Host-managed single-service workloads\n│   ├── wasm_cloud/          # wasmCloud CLI management (wash)\n│   ├── nats/                # NATS backbone health for wasmCloud\n│   ├── ghost/               # Ghost/zombie/orphan process detection\n│   ├── gateway/             # GatewayManager trait + Caddy impl\n│   ├── tunnel/              # TunnelManager trait + cloudflared impl\n│   ├── tailscale/           # Tailscale VPN status, peers, up/down\n│   ├── deploy/              # Git-based deployment runner + detector\n│   ├── projects/            # Local project browser, scaffold (create-better-t-stack), clone\n│   └── pi_agent/            # Pi Agent CLI integration (install, chat, sessions, skills)\n├── db/\n│   ├── mod.rs               # init_db (SQLite, auto-create ~/.postlab/data.db)\n│   ├── audit.rs             # Log actions for audit history\n│   ├── deployments.rs       # Deployment record CRUD\n│   └── agent_tasks.rs       # Scheduled agent task CRUD\n└── tui/\n    ├── mod.rs               # Terminal init + main event loop\n    ├── app.rs               # App state machine and background task management\n    ├── events.rs            # Keyboard dispatch (global + screen-specific)\n    └── screens/             # UI for all 9 top-level screens\n```\n\n---\n\n## Support\n\n### Package Managers\n\nDetected automatically at startup:\n\n- **Debian / Ubuntu**: `apt`\n- **Fedora / RHEL**: `dnf` / `yum`\n- **Arch**: `pacman`\n- **macOS**: `brew`\n\n### Container Engines\n\nDetected automatically — prefers `docker`, falls back to `podman`.\n\n### Firewalls\n\nDetected automatically at startup:\n\n- **Debian / Ubuntu**: `ufw`\n- **Fedora / RHEL / Arch**: `firewalld`\n- **macOS**: `pf`\n\n### Security Hardening Audits\n\n| Check | Severity | Action |\n| ----- | -------- | ------ |\n| SSH root login enabled | Critical | One-click fix |\n| SSH password auth enabled | High | One-click fix |\n| Firewall (ufw / firewalld / pf) inactive | High | One-click fix |\n| ASLR not fully enabled | Medium | One-click fix |\n| Auto-updates not configured | Low | One-click fix |\n\nEvery fix creates a `.bak.\u003ctimestamp\u003e` copy of the config file first, e.g., `/etc/ssh/sshd_config.bak.20260303T142031`.\n\n---\n\n## Roadmap\n\n- [ ] **Snapshots** — Btrfs/ZFS snapshot management.\n- [ ] **Web API** (axum) — Expose `core::Platform` over HTTP.\n- [ ] **Multi-service workloads** — Compose-level service graphs in the Workloads tab.\n- [ ] **SSH config hardening** — Full sshd_config audit, key rotation, and MFA setup.\n\n---\n\n## Changelog\n\n### v0.3.0 — 2026-06-28\n\nFirst feature release since v0.2.0. Highlights:\n\n- **User management** — list, create, and delete users with password and sudoers handling.\n- **WasmCloud + NATS** — service management, backbone provisioning, and a component inspector.\n- **Managed Docker services** — managed workloads, Podman support, and Firewalld/pf managers.\n- **Pi Agent** (formerly Zeroclaw) — chat, tools, tasks, sessions, skills, auth, and logs.\n- **Networking** — Gateway (Caddy), Tunnel (Cloudflare), and Tailscale tabs.\n- **Projects** and **Automation/Agent** screens, plus swap management, a Storage tab, and an Updates tab.\n- Installer now pulls per-platform tarballs from GitHub Releases (Linux x86_64/arm64, macOS arm64).\n\nSee [CHANGELOG.md](CHANGELOG.md) for the full history and the [v0.3.0 release](https://github.com/rifkyputra/postlab/releases/tag/v0.3.0) for downloads.\n\n---\n\n## Development\n\n### Requirements\n\n- Rust 1.75+\n- SQLite\n\n### Local Build\n\n```bash\nmake build   # Dev build\nmake release # Optimized release binary (~8–15 MB)\nmake run     # Build and run interactive mode\n```\n\n---\n\n## License\n\nThis project is licensed under the Apache License, Version 2.0.\nSee the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frifkyputra%2Fpostlab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frifkyputra%2Fpostlab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frifkyputra%2Fpostlab/lists"}