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
8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.git
*.md
*.bat
*.csv
*.log
*.test
__pycache__/
node_modules/
33 changes: 33 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Stage 1: Build
FROM golang:1.20-alpine AS builder
WORKDIR /app

# Copy module files and download dependencies
COPY go.mod go.sum ./
RUN go mod download

# Copy source files explicitly
COPY cmd/helios ./cmd/helios
COPY internal/ ./internal
COPY helios.docker.yaml .
COPY certs/ certs/

# Build the binary
RUN go build -o helios ./cmd/helios

# Stage 2: Runtime
FROM alpine:3.18
WORKDIR /app

# Copy built binary and config
COPY --from=builder /app/helios .
COPY helios.docker.yaml .
COPY certs/ certs/

# Create non-root user
RUN addgroup -S helios && adduser -S helios -G helios
USER helios

EXPOSE 8080 9090 9091
CMD ["./helios", "--config=helios.docker.yaml"]

2 changes: 2 additions & 0 deletions Dockerfile.backend
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FROM nginx:alpine
COPY default.conf /etc/nginx/conf.d/default.conf
133 changes: 98 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
[![License](https://img.shields.io/github/license/0xReLogic/Helios)](https://github.com/0xReLogic/Helios/blob/main/LICENSE)
[![Go Reference](https://pkg.go.dev/badge/github.com/0xReLogic/Helios.svg)](https://pkg.go.dev/github.com/0xReLogic/Helios)
[![Build Status](https://img.shields.io/github/actions/workflow/status/0xReLogic/Helios/build.yml?branch=main)](https://github.com/0xReLogic/Helios/actions)

</div>

Ultra-fast, production-grade L7 reverse proxy and load balancer - simple, extensible, and reliable.
Expand All @@ -30,7 +31,7 @@ Helios is a modern, production-grade reverse proxy and load balancer for microse
- Active health checks - Proactively monitors backend health with periodic requests
- **Request Rate Limiting**: Token bucket algorithm to prevent abuse and ensure fair usage
- **Circuit Breaker Pattern**: Prevents cascading failures by temporarily blocking requests to unhealthy services
- **Metrics and Monitoring**:
- **Metrics and Monitoring**:
- Real-time metrics collection and exposure
- Health status endpoints
- Backend performance monitoring
Expand All @@ -47,46 +48,46 @@ Helios is a modern, production-grade reverse proxy and load balancer for microse
```mermaid
graph TD
Client([Client]) -->|HTTP Request| RateLimit[Rate Limiter]

subgraph "Helios Load Balancer"
RateLimit --> CircuitBreaker[Circuit Breaker]
CircuitBreaker --> Helios[Helios Proxy]
Helios --> LoadBalancer[Load Balancing Strategy]
Helios --> HealthChecker[Health Checker]
Helios --> MetricsCollector[Metrics Collector]

subgraph "Health Monitoring"
HealthChecker --> PassiveChecks[Passive Health Checks]
HealthChecker --> ActiveChecks[Active Health Checks]
end

subgraph "Load Balancing Strategies"
LoadBalancer --> RoundRobin[Round Robin]
LoadBalancer --> LeastConn[Least Connections]
LoadBalancer --> WeightedRR[Weighted Round Robin]
LoadBalancer --> IPHash[IP Hash]
end

subgraph "Monitoring & Metrics"
MetricsCollector --> MetricsAPI[Metrics API :9090]
MetricsCollector --> HealthAPI[Health API :9090]
end
end

Helios -->|Forward Request| Backend1[Backend Server 1]
Helios -->|Forward Request| Backend2[Backend Server 2]
Helios -->|Forward Request| Backend3[Backend Server 3]

ActiveChecks -.->|Health Probe| Backend1
ActiveChecks -.->|Health Probe| Backend2
ActiveChecks -.->|Health Probe| Backend3

Backend1 -->|Response| Helios
Backend2 -->|Response| Helios
Backend3 -->|Response| Helios

Helios -->|HTTP Response| Client

MetricsAPI -.->|Monitoring Data| Monitoring[Monitoring System]
HealthAPI -.->|Health Status| Monitoring
```
Expand All @@ -103,12 +104,14 @@ graph TD
#### From Source

1. Clone the repository:

```bash
git clone https://github.com/0xReLogic/Helios.git
cd Helios
```

2. Build the project:

```bash
go build -o helios.exe ./cmd/helios
```
Expand Down Expand Up @@ -171,31 +174,31 @@ backends:
weight: 1

load_balancer:
strategy: "round_robin" # Options: "round_robin", "least_connections", "weighted_round_robin", "ip_hash"
strategy: "round_robin" # Options: "round_robin", "least_connections", "weighted_round_robin", "ip_hash"

health_checks:
active:
enabled: true
interval: 5 # Interval in seconds
timeout: 3 # Timeout in seconds
interval: 5 # Interval in seconds
timeout: 3 # Timeout in seconds
path: "/health"
passive:
enabled: true
unhealthy_threshold: 10 # Number of failures before marking as unhealthy
unhealthy_timeout: 15 # Time in seconds to keep backend unhealthy
unhealthy_threshold: 10 # Number of failures before marking as unhealthy
unhealthy_timeout: 15 # Time in seconds to keep backend unhealthy

rate_limit:
enabled: true # Disabled by default
max_tokens: 100 # Maximum tokens in bucket
refill_rate_seconds: 1 # Refill rate in seconds
enabled: true # Disabled by default
max_tokens: 100 # Maximum tokens in bucket
refill_rate_seconds: 1 # Refill rate in seconds

circuit_breaker:
enabled: true
max_requests: 100 # Max requests in half-open state
interval_seconds: 30 # Time window for failure counting
timeout_seconds: 15 # Time to wait before moving from open to half-open
failure_threshold: 50 # Number of failures to open circuit
success_threshold: 10 # Number of successes to close circuit
max_requests: 100 # Max requests in half-open state
interval_seconds: 30 # Time window for failure counting
timeout_seconds: 15 # Time to wait before moving from open to half-open
failure_threshold: 50 # Number of failures to open circuit
success_threshold: 10 # Number of successes to close circuit

admin_api:
enabled: true
Expand All @@ -204,13 +207,13 @@ admin_api:

metrics:
enabled: true
port: 9090 # Port for metrics server
path: "/metrics" # Path for metrics endpoint
port: 9090 # Port for metrics server
path: "/metrics" # Path for metrics endpoint

logging:
level: "info" # debug, info, warn, error
format: "text" # text (default) or json
include_caller: true # include caller information in logs
level: "info" # debug, info, warn, error
format: "text" # text (default) or json
include_caller: true # include caller information in logs
request_id:
enabled: true
header: "X-Request-ID"
Expand Down Expand Up @@ -291,15 +294,15 @@ backends:
weight: 1

load_balancer:
strategy: "round_robin" # round_robin, least_connections, weighted_round_robin, ip_hash
strategy: "round_robin" # round_robin, least_connections, weighted_round_robin, ip_hash

health_checks:
active:
enabled: true
interval: 5
timeout: 3
path: "/health"

circuit_breaker:
enabled: true
failure_threshold: 50
Expand All @@ -321,27 +324,89 @@ go build -o backend ./cmd/backend
## Monitoring & Management

### Metrics Endpoint

Access real-time metrics at `http://localhost:9090/metrics` (Prometheus format)

### Admin API

- Runtime backend management
- Strategy switching
- Strategy switching
- Health status monitoring
- JWT-protected endpoints

### Health Checks

- Active: Periodic backend health verification
- Passive: Request-based health tracking
- Circuit breaker: Automatic failure isolation

## Documentation

- [Plugin Development Guide](docs/plugin-development.md) - Learn how to create custom plugins
- Example plugins: `internal/plugins/examples`

## Contributing

We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

### 🧪 Local Development with Docker Compose

Helios can be run locally with three Nginx backends using Docker Compose. This setup validates plugin behavior, health checks, and load balancing.

#### 📦 Services

| Service | Port(s) | Description |
| ---------- | ------- | ---------------------------------------- |
| `helios` | 8080 | Load balancer entrypoint |
| | 9090 | Metrics endpoint (`/metrics`, `/health`) |
| | 9091 | Admin API (token-protected) |
| `backend1` | 8081 | Nginx backend with default response |
| `backend2` | 8082 | Nginx backend with default response |
| `backend3` | 8083 | Nginx backend with default response |

#### 🧱 Build Instructions

1. Ensure Docker and Docker Compose are installed.
2. Clone the repo and navigate to the root directory.
3. Build and launch:

```bash
docker-compose build --no-cache
docker-compose up
```

🔍 Health Check Behavior
Helios performs active health checks on / for each backend every 10 seconds. Backends respond with:

Backend is alive

If a backend fails to respond, it is marked unhealthy for 30 seconds.

🔐 Admin API
The Admin API is exposed on port 9091 and requires a token (configured in helios.docker.yaml). It provides:

- Backend status

- Plugin chain inspection

- Circuit breaker metrics

📊 Metrics
Available at:

- http://localhost:9090/metrics

- http://localhost:9090/health

🧩 Plugin Chain
The default plugin chain includes:

- logging: request logs with trace IDs

- size_limit: enforces payload size

- headers: injects custom headers

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
Expand All @@ -350,10 +415,8 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file

## Contributors

Thanks to all the amazing people who have contributed to Helios!
Thanks to all the amazing people who have contributed to Helios!

<a href="https://github.com/0xReLogic/Helios/graphs/contributors">
<img src="https://contrib.rocks/image?repo=0xReLogic/Helios" />
</a>


6 changes: 5 additions & 1 deletion cmd/helios/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"flag"
"fmt"
"net/http"
"os"
Expand All @@ -14,7 +15,10 @@ import (

func main() {
// Load configuration
cfg, err := config.LoadConfig("helios.yaml")
configPath := flag.String("config", "helios.yaml", "Path to config file")
flag.Parse()

cfg, err := config.LoadConfig(*configPath)
Comment on lines +18 to +21

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❌ Getting worse: Complex Method
main already has high cyclomatic complexity, and now it increases in Lines of Code from 125 to 127

Suppress

if err != nil {
logging.L().Fatal().Err(err).Msg("failed to load configuration")
}
Expand Down
7 changes: 7 additions & 0 deletions default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
server {
listen 80;
location / {
return 200 "Backend is alive\n";
add_header Content-Type text/plain;
}
}
51 changes: 51 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
version: "3.8"

services:
helios:
build: .
ports:
- "8080:8080"
- "9090:9090"
- "9091:9091"
volumes:
- ./helios.docker.yaml:/app/helios.docker.yaml
- ./certs:/app/certs
depends_on:
- backend1
- backend2
- backend3
Comment on lines +13 to +16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The depends_on directive in Docker Compose only ensures the startup order of services, but it does not wait for the services to be 'ready' (e.g., Nginx fully started and listening). For more robust dependency management, consider using wait-for-it.sh or a similar health-check based approach within your helios service's command or entrypoint.

healthcheck:
test:
[
"CMD",
"wget",
"--quiet",
"--tries=1",
"--spider",
"http://localhost:8080",
]
interval: 10s
timeout: 5s
retries: 3
restart: unless-stopped

backend1:
build:
context: .
dockerfile: Dockerfile.backend
ports:
- "8081:80"

backend2:
build:
context: .
dockerfile: Dockerfile.backend
ports:
- "8082:80"

backend3:
build:
context: .
dockerfile: Dockerfile.backend
ports:
- "8083:80"
Loading