Task Central
GitHub

Task Central

A self-hosted tracker for the machines in my homelab. It keeps the inventory, the setup checklist for each box, the maintenance schedule, and a Markdown document I can paste into Obsidian.

The Task Central dashboard: machine counts, recent machines, and a needs attention panel

Why it exists

A homelab grows one late night at a time. You spin up a VM to try something, get it working, and move on. Six months later you are looking at an IP you do not recognize, trying to remember which host it lives on, what it runs, and whether you ever got around to opening the right ports or setting up the firewall.

I kept meaning to write all of that down in Obsidian and kept not doing it, because writing the same twenty five lines of Markdown by hand for every new container is exactly the kind of chore that never happens. So the tracking and the document generation live in the same place now. I fill in a form while I am building the machine, and the notes come out the other end.

It is built for one person and one lab. There are no roles, no invitations, no per user data, and no accounts to create. It runs on a box I already own.

What it does

Everything hangs off a machine record. A machine is a VM, an LXC container, a physical box, a hypervisor host, or the network gear itself. The type you pick changes which fields you get, which tabs the detail page shows, and which templates apply, so a router record never asks you for a VMID.

Inventory
Identity, addressing, hardware, operating system, owner, purpose, and tags on one record. Search by name, IP, DNS record, or host. Filter by type, hypervisor, or tag. Retired gear is archived instead of deleted, so the history survives.
Checklists
Each machine is created with the checklist for its type already attached, copied from your templates. A VM comes out with twenty four steps covering provisioning, the OS, security, network, UniFi, DNS, backups, and validation. Editing a template later never rewrites work you have already done, and one button adds the steps a machine is missing.
Reminders
Recurring maintenance on an interval you set. Mark one done and the next due date rolls forward on its own.
Documents
Every machine renders through a Jinja template into Markdown, including its services, storage, network segments, dependencies, and checklist. Preview it, copy it, or download the file. Each generation is snapshotted, and the machine is flagged when a change has made its document stale.
Dependencies
Record what a machine needs in order to work, including things outside the app. Give a VM the name of a host you already track and the link is made for you, so the host page and its document list every guest running on it.
Alerts
An optional Telegram bot that sends plain text when pending tasks go stale or reminders come due. Reminder alerts are gated to a daily send time in your timezone.
Reachability
The detail page pings the stored address every thirty seconds. It is a sanity check rather than monitoring, and no reply does not prove a box is powered off.
Local assistant
A side panel wired to Ollama or any OpenAI compatible server on your own network. It only accepts private, local addresses, and it is off until you point it somewhere.

Screenshots

Adding a machine

Six steps, then a page that stays useful long after the build is done.

  1. Type. VM, LXC, physical, host, or network. The rest of the wizard reshapes itself around the answer.
  2. Identity and network. Name, VMID, status, IP, MAC, DNS record, operating system, deployment date, purpose, owner, tags.
  3. Hardware. CPU type and cores, memory, disk, storage location, GPU, network interface.
  4. Services and dependencies. What runs on it and on which ports, what it needs to function, and whether anything is reachable from outside the LAN.
  5. Checklist and reminders. Review what the templates generated for this type before committing.
  6. Review. Save it, then work the checklist as you build and generate the document when you are done.

Running it

Releases ship as a bundle with prebuilt, pinned images for amd64 and arm64. The installer generates the secrets, pulls the images, starts the containers, and verifies that they came up. Migrations run on backend startup, so there is no separate database step.

mkdir taskcentral
cd taskcentral

taskcentral_version=$(curl -fsSL https://github.com/lurry2020/taskcentral/releases/latest/download/VERSION)

curl -fLO "https://github.com/lurry2020/taskcentral/releases/download/v${taskcentral_version}/taskcentral-${taskcentral_version}.tar.gz"

tar -xzf "taskcentral-${taskcentral_version}.tar.gz"
cd "taskcentral-${taskcentral_version}"

./install.sh

Then open http://localhost:8484. A five step wizard handles the username, password, timezone, and integrations on first launch. The bundle also carries update, backup, restore, and uninstall scripts. Updates take a backup first and roll back if the health check fails.

  • The SQLite database is bind mounted at data/ next to the compose file.
  • Rotating logs are written to logs/ where your usual tooling can read them.
  • API documentation is served at /api/docs, health at /api/v1/health.
  • Set DATABASE_URL to point at Postgres instead of SQLite.

Manual

The full user and operations manual, thirty two chapters covering every screen, the workflows behind them, deployment, upgrades, backups, the API, security notes, troubleshooting, and the caveats worth knowing before you hit them. It opens right here, no download and no leaving the page.

Task Central User and Operations Manual

Searchable contents, thirty two sections, roughly two thousand four hundred lines.

It covers first-run setup, machine types and fields, checklists and templates, reminders, dependencies and host links, Obsidian generation, Telegram alerts, backup and restore, upgrading, and a troubleshooting chapter.

Under the hood

Backend Python 3.12, FastAPI, SQLAlchemy 2 with Alembic, Pydantic v2, sandboxed Jinja2 for rendering
Frontend React 18, TypeScript, Vite, Tailwind CSS v4, TanStack Query, React Hook Form with Zod
Serving nginx on 8484, reverse proxying /api to uvicorn on 8000
Database SQLite by default, Postgres through DATABASE_URL
Auth HMAC signed session tokens, PBKDF2 password hash, every API route behind middleware, password resettable from the CLI
Alerts An asyncio loop on a single worker, checking roughly every sixty seconds
Releases Multi architecture GHCR images built and published by GitHub Actions

What it is not

It is not monitoring.

It tracks what you built and what is still outstanding. The only live signal it collects is that ping, and it exists so you can tell at a glance whether the box you are reading about is answering.

It does not talk to Proxmox yet.

Today you type in what a machine is and what it runs. That keeps it useful for hardware, network gear, and anything else with no API to query. Reading from Proxmox directly is the next thing being built, and there is more on that below.

It is not multi user.

One login, no roles, no sharing. That is a scope decision for a homelab, not a missing feature.

It does not require Obsidian.

The output is plain Markdown from a template you can rewrite. Obsidian is just what it was built against, so the renderer matches its line break behavior.

It does not phone home.

No accounts, no telemetry, no external calls other than Telegram if you turn it on. The data is a SQLite file on your own machine, and it exports to JSON whenever you want it elsewhere.

Coming next

What is being worked on now. None of it has shipped yet, so treat this as intent rather than a promise.

In progress

Proxmox API integration

The one feature that turns a written record into a live one. Point Task Central at your Proxmox node or cluster with a read only API token and it pulls every VM and container it can see, matches them against what you have already documented, and fills in the rest.

  • Import what already exists. First run offers to create records for every guest on the cluster, prefilled with VMID, name, host node, cores, memory, disk, and network interface, so an established lab is documented in one pass instead of one form at a time.
  • Catch the drift. When someone bumps a VM from four cores to eight, or moves it to another node, the machine is flagged as out of step with what you wrote down, in the same place that already tracks stale documents.
  • Find the undocumented. Anything running on the cluster with no record gets surfaced instead of quietly existing. That gap is where the surprises live.
  • Live state on the detail page. Real power state, uptime, and resource use next to the record, so reachability stops being a single ping.
  • Read only by default. The token stays scoped to reads, nothing is written back to Proxmox, and the integration is off until you configure it.

Beyond that

  • More alert channels. ntfy, Discord, and plain webhooks alongside Telegram.
  • Scheduled backups. The backup script on a timer, with retention, instead of run it when you remember.
  • Attachments per machine. Config snippets, licence keys, and photos of the label on the back of the box.
  • Saved filters. Name a filter on the inventory and pin it, for the views you open every day.
  • A real dependency map. The host and guest links drawn out, so you can see what falls over when one box goes down.

Contact

Questions, ideas, and bug reports all welcome. Anything that belongs in the code is better as a GitHub issue, but this reaches me either way.

The code is on GitHub. Issues and pull requests are welcome, though I am building it for my own lab first.

github.com/lurry2020/taskcentral