Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
"words": [
"daltonbr",
"dylib",
"godotenv",
"joho",
"wolserver",
"wolserver"
]
}
8 changes: 6 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ on:
jobs:
test:
runs-on: ubuntu-latest

permissions:
contents: read
id-token: write

steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -32,7 +35,8 @@ jobs:
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
use_oidc: true
fail_ci_if_error: true
files: coverage.out

- name: Check formatting
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

# Build outputs
/wolserver
wol-server

# Go module / workspace
go.work
Expand Down
194 changes: 131 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,96 +3,164 @@

# WOL-Server

🔧 Project Overview
A lightweight HTTP server that sends Wake-on-LAN (WOL) magic packets to power on remote machines on your local network. Supports multiple devices through YAML configuration or direct API parameters.

This is a lightweight Go HTTP server that sends a Wake-on-LAN (WOL) magic packet to power on a remote machine on your local network.
## Quick Start

📦 How It Works
### Docker (Recommended)

- The server exposes an HTTP endpoint:
```yml
services:
wol-server:
image: ghcr.io/daltonbr/wol-server:latest
network_mode: "host" # Required for WOL broadcast on Linux
environment:
WOL_CONFIG: |
devices:
desktop:
mac: "00:11:22:33:44:55"
ip: "192.168.1.255"
port: 9

laptop:
mac: "aa:bb:cc:dd:ee:ff"
ip: "192.168.1.100"
restart: unless-stopped

# macOS users: network_mode: "host" doesn't work on Docker Desktop
# Use port mapping instead and comment out network_mode above:
# ports:
# - "5000:5000"

# Alternative: Mount a config file instead of using WOL_CONFIG env var
# volumes:
# - type: bind
# source: ~/.config/wol-server/config.yaml
# target: /root/.config/wol-server/config.yaml
# read_only: true
```

### Native Binary

```bash
GET /wake
```
# Install config
mkdir -p ~/.config/wol-server
cp config.example.yaml ~/.config/wol-server/config.yaml
# Edit config.yaml with your device details
````

- When accessed, it reads environment variables to determine:
- The target MAC address
- The destination IP and port
- Whether to use broadcast
- It then sends a WOL magic packet to wake the device
```bash
Comment thread
daltonbr marked this conversation as resolved.
# Run
go run .
```

🌱 Environment Variables
## Usage

Set these before running the server:
**Wake a configured device:**

| Variable | Example | Description |
| -------- | ------- | ----------- |
| WOL_MAC | 00:11:22:33:44:55 | Target machine's MAC address (required) |
| WOL_IP | 192.168.1.255 | Target machine's IP or broadcast (optional, default: 192.168.1.255) |
| WOL_PORT | 9 | UDP port for WOL (optional, default: 9) |
| WOL_BROADCAST | `true` or `false` | Use broadcast or direct IP (optional) |
```bash
curl http://localhost:5000/wake?device=desktop
```

▶️ Running
**Wake using direct parameters (no config needed):**

## Docker
```bash
curl "http://localhost:5000/wake?mac=00:11:22:33:44:55&ip=192.168.1.255"
```

`docker-compose.yml`
**Check server status:**

```yml
services:
wol-server:
image: ghcr.io/daltonbr/wol-server:latest
network_mode: "host"
environment:
ENV: production
WOL_MAC: "00:11:22:33:44:55" # Replace with your actual MAC address
WOL_IP: "192.168.1.255" # Your broadcast IP or direct device
WOL_PORT: "9" # Usually 7 or 9
WOL_BROADCAST: "true" # Set false if using directed IP (not supported yet)
restart: unless-stopped
```bash
curl http://localhost:5000/status
```

> [!TIP]
> Docker’s default bridge network does not allow broadcast e.g.`(192.168.1.255)` to go through - that is why we need `network-mode` set to `host`.
## Configuration

## How to use
### Option 1: Environment Variable (Docker)

You need to enable wake-on-lan on your Network card and probably enable this on your BIOS setup (usually is disabled to save energy)
[Check this guide for more details](https://www.windowscentral.com/software-apps/windows-11/how-to-enable-wake-on-lan-on-windows-11).
Set `WOL_CONFIG` with YAML content (see docker-compose example above).

Turn on PC - send the magical packet
### Option 2: Config File (Bare Metal)

```http
http://localhost:5000/wake
Create `~/.config/wol-server/config.yaml`:

```yaml
devices:
desktop:
mac: "00:11:22:33:44:55"
ip: "192.168.1.255"
port: 9 # optional, default: 9

laptop:
mac: "11:22:33:44:55:66"
ip: "192.168.1.255"
```

Check status
See [`config.example.yaml`](config.example.yaml) for more examples.

```http
http://localhost:5000/status
```
### Configuration Fields

📤 Publishing (GHCR)
| Field | Type | Description | Default |
| ----- | ---- | ----------- | ------- |
| mac | string | Target machine's MAC address (required) | - |
| ip | string | Target IP or broadcast address (required) | - |
| port | integer | UDP port for WOL | 9 |

To build and publish a multi-arch Docker image (specifically `linux/amd64`) to GitHub Container Registry (GHCR):
## API Reference

```bash
# Build for linux/amd64
docker build --platform linux/amd64 -t wol-server .
### Endpoints

#### `GET /wake`

Wake a device using either a configured device name or direct parameters.

**Query Parameters:**

Using configured device:

- `device` - Device name from config (required)

Using direct parameters:

- `mac` - MAC address in colon format (required)
- `ip` - Target IP or broadcast address (required)
- `port` - UDP port (optional, default: 9)

**Examples:**

# Tag with GHCR path and version
docker tag wol-server ghcr.io/daltonbr/wol-server:latest
docker tag wol-server ghcr.io/daltonbr/wol-server:<version>
```bash
# Using device name
GET /wake?device=desktop

# Push to GHCR
docker push ghcr.io/daltonbr/wol-server:latest
docker push ghcr.io/daltonbr/wol-server:<version>
# Using direct parameters
GET /wake?mac=00:11:22:33:44:55&ip=192.168.1.255&port=9
```

> 💡 You must be logged in to GHCR with a Personal Access Token (PAT) that has `write:packages` permission:
#### `GET /status`

Check if the server is running.

**Response:** `WOL service is running`

## Prerequisites

Your target machine must have:

- Wake-on-LAN enabled in BIOS/UEFI
- Wake-on-LAN enabled in network adapter settings
- Connected to power (or battery with WOL support)

[Guide: How to enable Wake-on-LAN on Windows 11](https://www.windowscentral.com/software-apps/windows-11/how-to-enable-wake-on-lan-on-windows-11)

## Alternative: Volume Mount Config

Instead of using `WOL_CONFIG` env var, you can mount a config file (see commented example in docker-compose above).

## Development

See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for:

> 💡 You must be logged in to GHCR using your GitHub username and a Personal Access Token (PAT) with `write:packages` permission:
>
> ```bash
> docker login ghcr.io
> ```
- Building from source (requires Go 1.25.5+)
- Running tests
- Cross-compilation
- Publishing releases
18 changes: 18 additions & 0 deletions config.example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Example WOL Server Configuration
# Copy this to ~/.config/wol-server/config.yaml or use WOL_CONFIG env var

devices:
desktop:
mac: "00:11:22:33:44:55"
ip: "192.168.1.255"
port: 9

gaming-pc:
mac: "aa:bb:cc:dd:ee:ff"
ip: "192.168.1.100"
port: 9

laptop:
mac: "11:22:33:44:55:66"
ip: "192.168.1.255"
# port defaults to 9 if not specified
Loading