# Galvanize

Galvanize Logo

A modern, Rust-based Wake-on-LAN control plane with HTTP/MQTT APIs, pluggable auth, and an optional React + shadcn Web UI.

CI Status Release Docker Pulls License

--- ## ✨ 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.

Web UI Screenshot

### 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