# Galvanize
A modern, Rust-based Wake-on-LAN control plane with HTTP/MQTT APIs, pluggable auth, and an optional React + shadcn Web UI.
---
## ✨ Features
- **🚀 Multi-Protocol Support** — Listen on HTTP REST API and/or MQTT for maximum flexibility
- **🔐 Pluggable Authentication** — Simple username/password auth or external OIDC provider integration
- **💾 Persistent Configuration** — WoL device configurations stored as JSON with hot-reload support
- **🎨 Modern Web UI** — Optional React + shadcn/ui dashboard (can be disabled with `--webui=false`)
- **📦 Easy Deployment** — Pre-built binaries, Docker images, and docker-compose ready
- **🦀 Built with Rust** — Fast, safe, and reliable
## 📋 Table of Contents
- [Installation](#-installation)
- [Quick Start](#-quick-start)
- [Configuration](#-configuration)
- [API Reference](#-api-reference)
- [Authentication](#-authentication)
- [Web UI](#-web-ui)
- [Docker](#-docker)
- [Development](#-development)
- [Related Projects](#-related-projects)
- [Contributing](#-contributing)
- [License](#-license)
## 📦 Installation
### Pre-built Binaries
Download the latest release for your platform from the [Releases](https://github.com/aitiome/galvanize/releases) page.
| Platform | Architecture | Download |
|----------|--------------|----------|
| Linux | x86_64 | `galvanize-linux-x86_64` |
| Linux | aarch64 | `galvanize-linux-aarch64` |
| macOS | x86_64 | `galvanize-darwin-x86_64` |
| macOS | aarch64 (Apple Silicon) | `galvanize-darwin-aarch64` |
| Windows | x86_64 | `galvanize-windows-x86_64.exe` |
### Docker
```bash
docker pull aitiome/galvanize:latest
# Run with default settings
docker run -d \
--name galvanize \
--network host \
-v ./config:/app/config \
aitiome/galvanize:latest
```
### Build from Source
```bash
# Clone the repository
git clone https://github.com/aitiome/galvanize.git
cd galvanize
# Build release binary
cargo build --release
# Build with Web UI (requires Node.js)
cd webui && pnpm install && pnpm build && cd ..
cargo build --release --features webui
```
## 🚀 Quick Start
1. **Start the server:**
```bash
galvanize serve --config ./config
```
2. **Add a device via API:**
```bash
curl -X POST http://localhost:8080/api/v1/devices \
-H "Content-Type: application/json" \
-H "Authorization: Bearer " \
-d '{
"name": "my-server",
"mac": "AA:BB:CC:DD:EE:FF",
"broadcast": "192.168.1.255",
"port": 9
}'
```
3. **Wake a device:**
```bash
curl -X POST http://localhost:8080/api/v1/devices/my-server/wake \
-H "Authorization: Bearer "
```
## ⚙️ Configuration
Galvanize uses a configuration directory structure:
```
config/
├── galvanize.toml # Main configuration file
├── devices/ # Device configurations (JSON)
│ ├── my-server.json
│ └── nas.json
└── users.toml # Local user credentials (optional)
```
### Main Configuration (`galvanize.toml`)
```toml
[server]
host = "0.0.0.0"
port = 8080
webui = true
[mqtt]
enabled = false
broker = "mqtt://localhost:1883"
topic_prefix = "galvanize"
client_id = "galvanize-server"
[auth]
# Authentication mode: "none", "basic", "oidc", or "both"
mode = "basic"
[auth.basic]
# Path to users file or inline users
users_file = "users.toml"
[auth.oidc]
enabled = false
issuer = "https://auth.example.com"
client_id = "galvanize"
client_secret = "${OIDC_CLIENT_SECRET}"
redirect_uri = "http://localhost:8080/auth/callback"
[storage]
# Directory for device configurations
path = "./config/devices"
# Watch for file changes and auto-reload
watch = true
```
### Device Configuration
```json
{
"id": "my-server",
"name": "My Server",
"mac": "AA:BB:CC:DD:EE:FF",
"broadcast": "192.168.1.255",
"port": 9,
"interface": null,
"tags": ["servers", "homelab"],
"metadata": {
"location": "Rack 1",
"os": "Ubuntu 22.04"
}
}
```
## 📡 API Reference
### HTTP Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/v1/devices` | List all devices |
| `GET` | `/api/v1/devices/:id` | Get device by ID |
| `POST` | `/api/v1/devices` | Create a new device |
| `PUT` | `/api/v1/devices/:id` | Update a device |
| `DELETE` | `/api/v1/devices/:id` | Delete a device |
| `POST` | `/api/v1/devices/:id/wake` | Send WoL magic packet |
| `POST` | `/api/v1/wake` | Wake device by MAC address (body) |
| `GET` | `/api/v1/health` | Health check endpoint |
### MQTT Topics
When MQTT is enabled, Galvanize subscribes to:
| Topic | Payload | Description |
|-------|---------|-------------|
| `galvanize/wake/:device_id` | `{}` | Wake device by ID |
| `galvanize/wake` | `{"mac": "AA:BB:..."}` | Wake by MAC address |
And publishes to:
| Topic | Description |
|-------|-------------|
| `galvanize/status` | Server status updates |
| `galvanize/events` | Wake events and results |
## 🔐 Authentication
### Basic Authentication
Create a `users.toml` file:
```toml
[[users]]
username = "admin"
# Generate with: galvanize hash-password
password_hash = "$argon2id$v=19$m=19456,t=2,p=1$..."
roles = ["admin"]
[[users]]
username = "user"
password_hash = "$argon2id$v=19$m=19456,t=2,p=1$..."
roles = ["user"]
```
### OIDC Authentication
Configure your OIDC provider in `galvanize.toml`:
```toml
[auth.oidc]
enabled = true
issuer = "https://auth.example.com"
client_id = "galvanize"
client_secret = "${OIDC_CLIENT_SECRET}"
redirect_uri = "http://localhost:8080/auth/callback"
scopes = ["openid", "profile", "email"]
```
## 🎨 Web UI
The Web UI provides a modern dashboard for managing your Wake-on-LAN devices.
### Features
- 📱 Responsive design for desktop and mobile
- 🌙 Light/Dark mode support
- 🔍 Search and filter devices
- 📊 Device status monitoring
- ⚡ One-click wake functionality
### Disable Web UI
To run in API-only mode:
```bash
galvanize serve --webui=false
```
Or in configuration:
```toml
[server]
webui = false
```
## 🐳 Docker
### Docker Compose
```yaml
version: "3.8"
services:
galvanize:
image: aitiome/galvanize:latest
container_name: galvanize
network_mode: host # Required for WoL broadcast
volumes:
- ./config:/app/config
environment:
- GALVANIZE_AUTH_MODE=basic
- OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}
restart: unless-stopped
```
### Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `GALVANIZE_HOST` | Server bind address | `0.0.0.0` |
| `GALVANIZE_PORT` | Server port | `8080` |
| `GALVANIZE_WEBUI` | Enable Web UI | `true` |
| `GALVANIZE_AUTH_MODE` | Auth mode | `none` |
| `GALVANIZE_CONFIG_PATH` | Config directory | `/app/config` |
| `OIDC_CLIENT_SECRET` | OIDC client secret | - |
## 🛠️ Development
### Prerequisites
- Rust 1.75+
- Node.js 20+ (for Web UI)
- pnpm (for Web UI)
### Setup
```bash
# Clone repository
git clone https://github.com/aitiome/galvanize.git
cd galvanize
# Install Rust dependencies
cargo build
# Install Web UI dependencies
cd webui
pnpm install
pnpm dev # Start dev server on :5173
```
### Project Structure
```
galvanize/
├── src/ # Rust server source
│ ├── main.rs
│ ├── api/ # HTTP API handlers
│ ├── mqtt/ # MQTT handlers
│ ├── auth/ # Authentication modules
│ ├── wol/ # Wake-on-LAN implementation
│ └── storage/ # Configuration persistence
├── webui/ # React Web UI
│ ├── src/
│ │ ├── components/ # shadcn/ui components
│ │ ├── pages/
│ │ └── lib/
│ └── package.json
├── config/ # Example configurations
├── docs/ # Documentation
└── Cargo.toml
```
### Running Tests
```bash
# Run all tests
cargo test
# Run with coverage
cargo tarpaulin
# Web UI tests
cd webui && pnpm test
```
## 🔗 Related Projects
Other projects from the [aitiome](https://github.com/aitiome) organization:
- **[outposts](https://github.com/aitiome/outposts)** — Distributed monitoring agents
- **[securitydept](https://github.com/aitiome/securitydept)** — Security policy management
## 🤝 Contributing
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on:
- Code of Conduct
- Development workflow
- Pull request process
- Coding standards
## 📄 License
Galvanize is dual-licensed under:
- [MIT License](LICENSE-MIT)
- [Apache License 2.0](LICENSE-APACHE)
You may choose either license at your option.
---
Made with ❤️ by aitiome