Timar

MIT · one container · no agents

Off is the right default. Unpatched isn't.

Timar wakes the machines in your homelab, updates them, reads their logs, and puts them back the way it found them. Nothing is installed on them — it needs SSH, and Wake-on-LAN for the ones that sleep. Between runs they stay dark, which is why most of them are off in the first place.

Run it Source on GitHub

amd64 + arm64Linux · OpenWrt · ProxmoxMIT licensed

Timar's dashboard listing six machines, each with a coloured light before its name: two green (up), three grey (asleep, on-demand), one red (down). Each row's actions are icon buttons — wake for the sleeping ones, then enrol, edit and remove. Below, a scheduled work panel shows a daily log sweep and a weekly update run with their last and next runs. The same dashboard in a light theme.
Three states, not two: grey asleep is a machine that is meant to be off, and it is not painted like a fault. A status page that shows both in red teaches you to ignore red. Servers are added, edited, enrolled and removed from the same page.

The problem

A sleeping machine cannot phone home.

Homelab machines are mostly off. The GPU box runs when you need it, the build server sits dark for a week. Tools built for always-on fleets assume an agent that reports in — the one thing a powered-down machine cannot do. So the machines that go longest without a security update are the ones nothing is watching.

Timar inverts it. Waking the host is step one of the job, and shutting it back down is the last. A machine that was off before the run is off after it.

What a run does

Wake, work, and put it back.

  1. Wake what is asleep A magic packet, or qm start on the hypervisor for a guest — a VM has no wake address of its own. For another subnet, a relay on that segment sends the packet.
  2. Update it with the command its platform actually has apt on Debian, dist-upgrade on Proxmox, or your own command. OpenWrt is skipped by default: an unattended apk upgrade can fill the overlay or break a kernel module on the machine carrying the session you would repair it from.
  3. Sweep the logs while it is up System log errors, disks past a threshold, stopped containers — and scheduled jobs on that machine that did not run today. Watching for absence is the point.
  4. Shut down whatever started off Guests first, then their hypervisor, in order. Anything that was already running is left running.
An archived update run, summarised as five updated, none failed, one skipped. Three machines are annotated 'woken, updated, shut down again'; two that were already on carry no annotation; the OpenWrt router is marked skipped because no update command is configured for it. The same update run in a light theme.
A run says what it did to each machine. The three annotated lines were asleep before the run and are asleep again; the router was skipped, not quietly left out.

The reports outlive the notification. Every finished run is archived, so a disk creeping upward or an update failing every Friday shows up as a series. Telegram delivery is a copy, not the only place the findings exist.

An archived log sweep: one machine with findings, none unreachable, three asleep. A written assessment at the top singles out a disk at 91 percent and a drive reporting a pending sector, and says which of the two is the more urgent. Below it, the raw per-host findings — the two smartd lines and the disk, then 'clean' for two hosts and 'offline, not checked' for the three that were asleep. The same log sweep in a light theme.
The written assessment sits above the findings it came from, never instead of them. A machine that was asleep is not checked, not clean — a sweep does not wake the fleet, and calling an unchecked host healthy is the one thing a status page must not do.

Measured, not assumed

The failures here are the quiet kind.

A magic packet that never leaves the host. A disk check that fails and reports all-clear. A schedule that stops firing and logs nothing. None of these announce themselves, so the decisions behind them were measured, not reasoned about — the measurements are in ARCHITECTURE.md.

0 → 1

Packets on the wire

Wake-on-LAN from a bridge network: the send succeeds, no error, and tcpdump on the LAN sees nothing. Host networking, same image, same button: one packet. That is why the compose file ships network_mode: host.

3.02s → 0.01s

Cold and cached probes

Most of the fleet is supposed to be unreachable, so a probe timeout is the normal case. Probes run in parallel behind a short TTL: the page costs one timeout, not one per sleeping machine.

126 MB

The whole thing

One Alpine image, running as a non-root fixed UID, for amd64 and arm64. A Raspberry Pi is a first-class host — it is what Timar is written on.

Platforms

Commands that exist on the machine you pointed at.

A check that cannot run on a platform says so, instead of reporting all-clear. Every command was tried on a real host of that platform first: one df flag GNU accepts and busybox rejects once made a disk check that passed on every router.

PlatformSystem logDiskContainersUnattended updates
Linux (systemd)journalctlyesDockeryes
Proxmox VEjournalctlyesguests via qmyes
OpenWrtlogreadyes—off by default

Run it

One container, one volume.

$ curl -O https://raw.githubusercontent.com/orkun-soylu/timar/main/docker-compose.yml
$ docker compose up -d

Open http://<host>:8080 and create the operator account — nothing else answers until you do. Everything an installation is — config, credentials, state, reports, the SSH key — lives in /data, so backup and migration are cp -a.

The edit dialog for vm-01: name, address, SSH user and platform; Wake-on-LAN MAC and relay; 'Guest of hv-01' with VM id 101; update command, update timeout, and context for the log analysis. The same dialog in a light theme.
Servers are managed from the dashboard. Add, edit and enrol open in a dialog like this one; underneath it is still just config.yaml, which you can edit by hand.

A VM has no wake address of its own, so it names the hypervisor that starts it and inherits on-demand from it — otherwise every night it spends off would be reported as an outage.

Do not expose this to the internet. Timar holds an SSH key that reaches every machine it manages and can grant itself sudo on them. Keep it on a private network, or behind a reverse proxy you control.

Nothing to install on the fleet

SSH, and Wake-on-LAN for the machines that sleep. Timar generates its own keypair on first use, installs it with your password once, and pins each host key on first sight.

Optional, not required

A model to summarise sweeps (Anthropic, any OpenAI-compatible endpoint, or Ollama) and Telegram for delivery. Without them everything still works — you get the raw findings instead of a written assessment.