A lightweight service registry consisting of a Go REST API server and a Cobra-powered CLI client. To keep Github Actions VMs up in a controlled manner, to deploy platforms.
Zenith is a small distributed service management project written in Go. It consists of two independent applications:
- Zenith Server — exposes a REST API for managing services.
- Zenith CLI — a Cobra-based command-line application for interacting with the server.
The project demonstrates:
- REST API development in Go
- Cobra CLI application design
- End-to-end testing with GitHub Actions
- Multi-runner integration testing
- Tailscale-based networking between CI runners
+----------------------+
| Zenith CLI |
| (Cobra Client) |
+----------+-----------+
|
HTTP REST API
|
v
+----------------------+
| Zenith Server |
| Service Registry |
+----------------------+
- REST API
- Register services
- Remove services
- Query service status
- Health endpoint
- In-memory service registry
- Thread-safe data access
- Built with Cobra
- Simple command structure
- Supports remote servers through
--url - Continuous health checking
- Continuous service monitoring
.
├── client/
│ ├── cmd/
│ └── main.go
│
├── server/
│ └── main.go
│
├── handlers/
├── models/
├── tests/
└── go.mod
go build -o zenith_server server/main.gogo build -o zenith_client client/main.goStart the server:
./zenith_server 8080Use the CLI:
./zenith_client --url http://localhost:8080 pingadd Add a service
check Continuously check service availability
ping Ping the server
remove Remove a service
status Query service status
Global flag:
--url
Default:
http://0.0.0.0:8080
Examples:
# Ping server
zenith_client ping
# Register a service
zenith_client add api
# Check a service
zenith_client check api
# Check every registered service
zenith_client check
# Service status
zenith_client status api
# Remove a service
zenith_client remove api| Method | Endpoint | Description |
|---|---|---|
| GET | /ping |
Health endpoint |
| POST | /add |
Register a service |
| DELETE* | /remove |
Remove a service |
| GET | /status |
Query service status |
Example:
curl -X POST http://localhost:8080/add \
-H "Content-Type: application/json" \
-d '{"service_name":"example"}'Zenith includes an end-to-end GitHub Actions workflow that validates the complete distributed system.
The workflow performs the following steps:
- Build the server binary.
- Build the CLI binary.
- Upload both artifacts.
- Start the server on a dedicated GitHub Actions runner.
- Connect all runners using Tailscale.
- Register the main server service.
- Wait until the server becomes reachable.
- Launch two independent client runners.
- Register services from each client.
- Continuously verify service availability.
- Remove services one by one.
- Finally remove the server service and complete the shutdown sequence.
This simulates a small distributed environment where multiple machines communicate with a central Zenith server over a private Tailscale network.
Server
│
├── Register "main_service"
│
├──────────────┐
│ │
Client-01 Client-02
│ │
Register Register
│ │
Check Check
│ │
Remove Remove
└──────┬───────┘
│
Remove server
- Go
- Cobra CLI
- net/http
- GitHub Actions
- Tailscale
MIT License.