Self-hosted service
Trugamr/wol avatar
Trugamr/wol

Trugamr/wol: Wake-On-LAN from the Shell, a Browser Tab, or a Cron Line

🦭 Wake up your devices with a single command or click. A Wake-On-LAN tool that works via CLI and web interface.

699 stars24 forksGoMIT

At a glance

What is it?
wol is a small Go program that sends Wake-On-LAN magic packets from a CLI, a local web interface, or a cron schedule. It is a good fit if your machines have stable MAC addresses and live on a network you control, and a poor fit if you need to wake devices across subnets you cannot broadcast into.
Who is it for?
Adopt wol if you have a handful of machines on one LAN or a few known subnets, you want wake-ups from a shell script or a browser button, and you are comfortable editing a YAML file that lives at /etc/wol/config.yaml or ~/.wol/config.yaml. Do not adopt it if your target hosts sit behind routers that drop directed broadcasts, if you need wake-on-WAN, or if you want a web UI with authentication built in; the README points at examples/reverse-proxy.yml for basic auth instead.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 94 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap between a sleeping machine and the person who needs it

A machine that is powered off but has Wake-On-LAN enabled will boot when its network card sees a magic packet: a frame containing the target's MAC address repeated sixteen times. Producing that frame is not hard, but doing it repeatedly, for several machines, from a laptop or a phone, is where ad hoc shell one-liners stop scaling. wol exists to hold a list of machines with names and MAC addresses, and to send the packet on command. The README describes the intended audience indirectly through its features: people who run a home server or a small lab, keep more than one machine asleep, and want to wake a specific one without remembering which MAC belongs to which box. The two interfaces, a CLI and a web page served on port 7777, cover the two common cases: scripting and a quick click from a browser. Nothing in the material suggests it targets fleet management or enterprise networks, and the configuration model (a single YAML file, or one environment variable holding the same YAML) confirms that scope.

One binary, one config file, two front ends

The program is written in Go and ships as a single binary per platform, which matters because the packet-sending path is the whole product. Configuration is a YAML document with four top-level keys: machines, server, broadcast, and the optional schedules. Each machine entry needs a name and a mac, and may carry an ip used for status checking and its own broadcast block. The broadcast block has address and port fields, with a documented default of 255.255.255.255:9. The server block holds a listen address, defaulting to :7777. The schedules block is a list of entries with a machine name, a cron expression, and an optional label. The web interface is started by the serve subcommand and, per the README, lists all configured machines and offers one-click wake. That is the entire data flow: read config, build a magic packet per machine, send it to the resolved broadcast address and port. There is no agent on the target, no handshake, and no confirmation that the machine actually booted. The ip field enables status checking, but the README does not describe the mechanism beyond calling it optional and tying it to status, so treat any status display as a reachability signal rather than proof of a successful wake.

Getting it running: install paths and the commands that matter

Three installation routes are documented. Pre-built binaries are published for Linux (x86_64, arm64, armv7), macOS (x86_64, arm64), and Windows (x86_64). With a Go toolchain you can run go install github.com/trugamr/wol@latest. With Docker, the README gives docker run --network host -v $(pwd)/config.yaml:/etc/wol/config.yaml ghcr.io/trugamr/wol:latest, and a compose example that adds command: serve to start the web interface. The image tags are latest and X.Y.Z for releases, plus edge for the tip of main. Once installed, the CLI surface is small: wol list, wol send --name desktop, wol send --mac "00:11:22:33:44:55", wol serve, wol serve --config /etc/wol/config.yaml, and wol version. A single send can override the destination with --broadcast and --port. Config resolution is worth reading carefully: wol looks in ./config.yaml, then ~/.wol/config.yaml, then /etc/wol/config.yaml, and an explicit --config path is authoritative, meaning it must exist and it disables both the search path and the WOL_CONFIG environment variable. The README notes that serve logs which config source it loaded, which is the fastest way to debug a config that seems to be ignored.

Broadcast routing is the failure mode you will actually hit

The README is unusually direct about the most common way wol fails: on a host with more than one network interface, such as WSL2 or a machine with Docker bridges, the OS may send the packet out the wrong interface and the target never receives it. The fix is to stop using 255.255.255.255 and set the broadcast address of the target's own subnet instead, for example 192.168.1.255 for a device at 192.168.1.100/24. wol supports this at three levels, and the precedence order is CLI flag, then per-machine config, then global config, then the built-in default. Per-machine broadcast blocks exist precisely for machines on different subnets or VLANs, and unset fields inherit from the global block. This is a real constraint, not a footnote: if your targets sit behind a router that does not forward directed broadcasts, no amount of configuration in wol will reach them, because Wake-On-LAN is a layer 2 mechanism and wol only emits the frame. The project also cannot wake a machine whose NIC is not armed, and it cannot report that a wake succeeded. It sends and exits.

Scheduled wake-ups and how misconfiguration surfaces

The schedules section turns serve into a small cron runner. Each entry names a machine and a cron expression, with standard five-field syntax plus the @hourly, @daily, @weekly, @monthly and @every 1h30m descriptors. The design choice worth noting is validation at startup: a schedule referencing an unknown machine, or carrying an invalid cron expression, makes wol serve exit with an error. That is better than the alternative, where a typo produces a job that silently never fires, and it means you find out about a bad schedule the moment you restart the service rather than the first Saturday it should have run. Two operational details follow from the README. Expressions are evaluated in the server's local time, so a container needs TZ set, for example TZ=America/New_York. And omitting the schedules key entirely disables scheduling, with serve behaving exactly as before, so the feature is additive and does not change the behaviour of an existing config. The README does not describe retry behaviour, overlap handling, or what happens if a scheduled wake runs while a previous one is still in flight, and there is no material here about persistence of schedule state, so assume each firing is independent and stateless.

Where wol stops and something else should start

The obvious alternative is etherwake, or a one-line shell function built on it. The difference in approach is configuration versus invocation: etherwake takes a MAC address on the command line every time, so the mapping from name to MAC lives in your head, your shell history, or a wrapper script you maintain. wol moves that mapping into a YAML file with names, adds per-machine broadcast overrides, and exposes the same list through a web page. If you wake exactly one machine and you already have a working script, wol adds a config file and a service for no gain. If you want a web interface with authentication, wol does not ship one; the README points to examples/reverse-proxy.yml for running it behind a reverse proxy with basic auth and HTTPS, which means you are deploying a proxy alongside it. And if your machines are on networks you cannot broadcast into, the correct tool is not a better WOL client but a network path that permits the packet, or a different wake mechanism entirely, such as a smart plug or a BMC. wol is deliberately narrow, and the narrowness is the point.

Maintenance, packaging, and the MIT licence in practice

The release history shows v0.1.0 in May 2025, then v0.2.0 and v0.3.0 one day apart in June 2026. That is a project still finding its shape, and the jump from a single early release to two releases in twenty-four hours suggests active but uneven development rather than a settled surface. The practical consequence is that config keys and CLI flags may still move between minor versions, so pinning X.Y.Z in a Docker deployment is the lower-risk choice, with edge reserved for testing unreleased changes. The image tags support exactly that: latest and X.Y.Z track named releases, edge tracks main. The licence is MIT, which is permissive and places few obligations on how you redistribute or modify the code; that is a factual statement about the licence identifier, not legal advice, and if you plan to embed the binary in a product you should read the licence text yourself. Operationally, the upgrade cost is low because the artifact is a single binary and the state is a YAML file you own. The thing to watch on upgrade is the config schema, particularly if schedules or the broadcast precedence rules change. Because serve logs which config source it loaded at startup and validates schedules immediately, a bad upgrade tends to fail loudly on the first run rather than quietly at 02:00 on a Saturday.

Editorial conclusion

Adopt wol if you have a handful of machines on one LAN or a few known subnets, you want wake-ups from a shell script or a browser button, and you are comfortable editing a YAML file that lives at /etc/wol/config.yaml or ~/.wol/config.yaml. Do not adopt it if your target hosts sit behind routers that drop directed broadcasts, if you need wake-on-WAN, or if you want a web UI with authentication built in; the README points at examples/reverse-proxy.yml for basic auth instead. Before you rely on it, verify three things on your own hardware: that the machine's BIOS and NIC have Wake-On-LAN enabled and that the OS keeps the NIC armed in the power state you use, that a magic packet sent to 255.255.255.255:9 actually reaches the target from the host running wol (the README warns that multi-interface hosts such as WSL2 or Docker bridge setups may send it out the wrong interface), and that your cron schedules fire in the timezone you expect, since expressions are evaluated in the server's local time and a container needs TZ set explicitly.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. Trugamr/wol on GitHub
Community notes

Community notes