Skip to content

Commit a8fb6f4

Browse files
authored
Add Dockerfile and Compose Setup for Helios (#39)
* Add Dockerfile and Compose setup for Helios with 3 backend services and config mount * Patch Dockerfile to avoid recursive copy and run Helios as non-root user * feat: add Docker Compose setup, backend config, and dynamic config loading
1 parent eb918e7 commit a8fb6f4

File tree

9 files changed

+302
-54
lines changed

9 files changed

+302
-54
lines changed

.dockerignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.git
2+
*.md
3+
*.bat
4+
*.csv
5+
*.log
6+
*.test
7+
__pycache__/
8+
node_modules/

Dockerfile

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Stage 1: Build
2+
FROM golang:1.20-alpine AS builder
3+
WORKDIR /app
4+
5+
# Copy module files and download dependencies
6+
COPY go.mod go.sum ./
7+
RUN go mod download
8+
9+
# Copy source files explicitly
10+
COPY cmd/helios ./cmd/helios
11+
COPY internal/ ./internal
12+
COPY helios.docker.yaml .
13+
COPY certs/ certs/
14+
15+
# Build the binary
16+
RUN go build -o helios ./cmd/helios
17+
18+
# Stage 2: Runtime
19+
FROM alpine:3.18
20+
WORKDIR /app
21+
22+
# Copy built binary and config
23+
COPY --from=builder /app/helios .
24+
COPY helios.docker.yaml .
25+
COPY certs/ certs/
26+
27+
# Create non-root user
28+
RUN addgroup -S helios && adduser -S helios -G helios
29+
USER helios
30+
31+
EXPOSE 8080 9090 9091
32+
CMD ["./helios", "--config=helios.docker.yaml"]
33+

Dockerfile.backend

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
FROM nginx:alpine
2+
COPY default.conf /etc/nginx/conf.d/default.conf

README.md

Lines changed: 98 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
[![License](https://img.shields.io/github/license/0xReLogic/Helios)](https://github.com/0xReLogic/Helios/blob/main/LICENSE)
88
[![Go Reference](https://pkg.go.dev/badge/github.com/0xReLogic/Helios.svg)](https://pkg.go.dev/github.com/0xReLogic/Helios)
99
[![Build Status](https://img.shields.io/github/actions/workflow/status/0xReLogic/Helios/build.yml?branch=main)](https://github.com/0xReLogic/Helios/actions)
10+
1011
</div>
1112

1213
Ultra-fast, production-grade L7 reverse proxy and load balancer - simple, extensible, and reliable.
@@ -30,7 +31,7 @@ Helios is a modern, production-grade reverse proxy and load balancer for microse
3031
- Active health checks - Proactively monitors backend health with periodic requests
3132
- **Request Rate Limiting**: Token bucket algorithm to prevent abuse and ensure fair usage
3233
- **Circuit Breaker Pattern**: Prevents cascading failures by temporarily blocking requests to unhealthy services
33-
- **Metrics and Monitoring**:
34+
- **Metrics and Monitoring**:
3435
- Real-time metrics collection and exposure
3536
- Health status endpoints
3637
- Backend performance monitoring
@@ -47,46 +48,46 @@ Helios is a modern, production-grade reverse proxy and load balancer for microse
4748
```mermaid
4849
graph TD
4950
Client([Client]) -->|HTTP Request| RateLimit[Rate Limiter]
50-
51+
5152
subgraph "Helios Load Balancer"
5253
RateLimit --> CircuitBreaker[Circuit Breaker]
5354
CircuitBreaker --> Helios[Helios Proxy]
5455
Helios --> LoadBalancer[Load Balancing Strategy]
5556
Helios --> HealthChecker[Health Checker]
5657
Helios --> MetricsCollector[Metrics Collector]
57-
58+
5859
subgraph "Health Monitoring"
5960
HealthChecker --> PassiveChecks[Passive Health Checks]
6061
HealthChecker --> ActiveChecks[Active Health Checks]
6162
end
62-
63+
6364
subgraph "Load Balancing Strategies"
6465
LoadBalancer --> RoundRobin[Round Robin]
6566
LoadBalancer --> LeastConn[Least Connections]
6667
LoadBalancer --> WeightedRR[Weighted Round Robin]
6768
LoadBalancer --> IPHash[IP Hash]
6869
end
69-
70+
7071
subgraph "Monitoring & Metrics"
7172
MetricsCollector --> MetricsAPI[Metrics API :9090]
7273
MetricsCollector --> HealthAPI[Health API :9090]
7374
end
7475
end
75-
76+
7677
Helios -->|Forward Request| Backend1[Backend Server 1]
7778
Helios -->|Forward Request| Backend2[Backend Server 2]
7879
Helios -->|Forward Request| Backend3[Backend Server 3]
79-
80+
8081
ActiveChecks -.->|Health Probe| Backend1
8182
ActiveChecks -.->|Health Probe| Backend2
8283
ActiveChecks -.->|Health Probe| Backend3
83-
84+
8485
Backend1 -->|Response| Helios
8586
Backend2 -->|Response| Helios
8687
Backend3 -->|Response| Helios
87-
88+
8889
Helios -->|HTTP Response| Client
89-
90+
9091
MetricsAPI -.->|Monitoring Data| Monitoring[Monitoring System]
9192
HealthAPI -.->|Health Status| Monitoring
9293
```
@@ -103,12 +104,14 @@ graph TD
103104
#### From Source
104105

105106
1. Clone the repository:
107+
106108
```bash
107109
git clone https://github.com/0xReLogic/Helios.git
108110
cd Helios
109111
```
110112

111113
2. Build the project:
114+
112115
```bash
113116
go build -o helios.exe ./cmd/helios
114117
```
@@ -171,31 +174,31 @@ backends:
171174
weight: 1
172175

173176
load_balancer:
174-
strategy: "round_robin" # Options: "round_robin", "least_connections", "weighted_round_robin", "ip_hash"
175-
177+
strategy: "round_robin" # Options: "round_robin", "least_connections", "weighted_round_robin", "ip_hash"
178+
176179
health_checks:
177180
active:
178181
enabled: true
179-
interval: 5 # Interval in seconds
180-
timeout: 3 # Timeout in seconds
182+
interval: 5 # Interval in seconds
183+
timeout: 3 # Timeout in seconds
181184
path: "/health"
182185
passive:
183186
enabled: true
184-
unhealthy_threshold: 10 # Number of failures before marking as unhealthy
185-
unhealthy_timeout: 15 # Time in seconds to keep backend unhealthy
187+
unhealthy_threshold: 10 # Number of failures before marking as unhealthy
188+
unhealthy_timeout: 15 # Time in seconds to keep backend unhealthy
186189

187190
rate_limit:
188-
enabled: true # Disabled by default
189-
max_tokens: 100 # Maximum tokens in bucket
190-
refill_rate_seconds: 1 # Refill rate in seconds
191+
enabled: true # Disabled by default
192+
max_tokens: 100 # Maximum tokens in bucket
193+
refill_rate_seconds: 1 # Refill rate in seconds
191194

192195
circuit_breaker:
193196
enabled: true
194-
max_requests: 100 # Max requests in half-open state
195-
interval_seconds: 30 # Time window for failure counting
196-
timeout_seconds: 15 # Time to wait before moving from open to half-open
197-
failure_threshold: 50 # Number of failures to open circuit
198-
success_threshold: 10 # Number of successes to close circuit
197+
max_requests: 100 # Max requests in half-open state
198+
interval_seconds: 30 # Time window for failure counting
199+
timeout_seconds: 15 # Time to wait before moving from open to half-open
200+
failure_threshold: 50 # Number of failures to open circuit
201+
success_threshold: 10 # Number of successes to close circuit
199202

200203
admin_api:
201204
enabled: true
@@ -204,13 +207,13 @@ admin_api:
204207

205208
metrics:
206209
enabled: true
207-
port: 9090 # Port for metrics server
208-
path: "/metrics" # Path for metrics endpoint
210+
port: 9090 # Port for metrics server
211+
path: "/metrics" # Path for metrics endpoint
209212

210213
logging:
211-
level: "info" # debug, info, warn, error
212-
format: "text" # text (default) or json
213-
include_caller: true # include caller information in logs
214+
level: "info" # debug, info, warn, error
215+
format: "text" # text (default) or json
216+
include_caller: true # include caller information in logs
214217
request_id:
215218
enabled: true
216219
header: "X-Request-ID"
@@ -291,15 +294,15 @@ backends:
291294
weight: 1
292295
293296
load_balancer:
294-
strategy: "round_robin" # round_robin, least_connections, weighted_round_robin, ip_hash
297+
strategy: "round_robin" # round_robin, least_connections, weighted_round_robin, ip_hash
295298
296299
health_checks:
297300
active:
298301
enabled: true
299302
interval: 5
300303
timeout: 3
301304
path: "/health"
302-
305+
303306
circuit_breaker:
304307
enabled: true
305308
failure_threshold: 50
@@ -321,27 +324,89 @@ go build -o backend ./cmd/backend
321324
## Monitoring & Management
322325

323326
### Metrics Endpoint
327+
324328
Access real-time metrics at `http://localhost:9090/metrics` (Prometheus format)
325329

326330
### Admin API
331+
327332
- Runtime backend management
328-
- Strategy switching
333+
- Strategy switching
329334
- Health status monitoring
330335
- JWT-protected endpoints
331336

332337
### Health Checks
338+
333339
- Active: Periodic backend health verification
334340
- Passive: Request-based health tracking
335341
- Circuit breaker: Automatic failure isolation
336342

337343
## Documentation
344+
338345
- [Plugin Development Guide](docs/plugin-development.md) - Learn how to create custom plugins
339346
- Example plugins: `internal/plugins/examples`
340347

341348
## Contributing
342349

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

352+
### 🧪 Local Development with Docker Compose
353+
354+
Helios can be run locally with three Nginx backends using Docker Compose. This setup validates plugin behavior, health checks, and load balancing.
355+
356+
#### 📦 Services
357+
358+
| Service | Port(s) | Description |
359+
| ---------- | ------- | ---------------------------------------- |
360+
| `helios` | 8080 | Load balancer entrypoint |
361+
| | 9090 | Metrics endpoint (`/metrics`, `/health`) |
362+
| | 9091 | Admin API (token-protected) |
363+
| `backend1` | 8081 | Nginx backend with default response |
364+
| `backend2` | 8082 | Nginx backend with default response |
365+
| `backend3` | 8083 | Nginx backend with default response |
366+
367+
#### 🧱 Build Instructions
368+
369+
1. Ensure Docker and Docker Compose are installed.
370+
2. Clone the repo and navigate to the root directory.
371+
3. Build and launch:
372+
373+
```bash
374+
docker-compose build --no-cache
375+
docker-compose up
376+
```
377+
378+
🔍 Health Check Behavior
379+
Helios performs active health checks on / for each backend every 10 seconds. Backends respond with:
380+
381+
Backend is alive
382+
383+
If a backend fails to respond, it is marked unhealthy for 30 seconds.
384+
385+
🔐 Admin API
386+
The Admin API is exposed on port 9091 and requires a token (configured in helios.docker.yaml). It provides:
387+
388+
- Backend status
389+
390+
- Plugin chain inspection
391+
392+
- Circuit breaker metrics
393+
394+
📊 Metrics
395+
Available at:
396+
397+
- http://localhost:9090/metrics
398+
399+
- http://localhost:9090/health
400+
401+
🧩 Plugin Chain
402+
The default plugin chain includes:
403+
404+
- logging: request logs with trace IDs
405+
406+
- size_limit: enforces payload size
407+
408+
- headers: injects custom headers
409+
345410
## License
346411

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

351416
## Contributors
352417

353-
Thanks to all the amazing people who have contributed to Helios!
418+
Thanks to all the amazing people who have contributed to Helios!
354419

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

cmd/helios/main.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"flag"
45
"fmt"
56
"net/http"
67
"os"
@@ -14,7 +15,10 @@ import (
1415

1516
func main() {
1617
// Load configuration
17-
cfg, err := config.LoadConfig("helios.yaml")
18+
configPath := flag.String("config", "helios.yaml", "Path to config file")
19+
flag.Parse()
20+
21+
cfg, err := config.LoadConfig(*configPath)
1822
if err != nil {
1923
logging.L().Fatal().Err(err).Msg("failed to load configuration")
2024
}

default.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
server {
2+
listen 80;
3+
location / {
4+
return 200 "Backend is alive\n";
5+
add_header Content-Type text/plain;
6+
}
7+
}

docker-compose.yaml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
version: "3.8"
2+
3+
services:
4+
helios:
5+
build: .
6+
ports:
7+
- "8080:8080"
8+
- "9090:9090"
9+
- "9091:9091"
10+
volumes:
11+
- ./helios.docker.yaml:/app/helios.docker.yaml
12+
- ./certs:/app/certs
13+
depends_on:
14+
- backend1
15+
- backend2
16+
- backend3
17+
healthcheck:
18+
test:
19+
[
20+
"CMD",
21+
"wget",
22+
"--quiet",
23+
"--tries=1",
24+
"--spider",
25+
"http://localhost:8080",
26+
]
27+
interval: 10s
28+
timeout: 5s
29+
retries: 3
30+
restart: unless-stopped
31+
32+
backend1:
33+
build:
34+
context: .
35+
dockerfile: Dockerfile.backend
36+
ports:
37+
- "8081:80"
38+
39+
backend2:
40+
build:
41+
context: .
42+
dockerfile: Dockerfile.backend
43+
ports:
44+
- "8082:80"
45+
46+
backend3:
47+
build:
48+
context: .
49+
dockerfile: Dockerfile.backend
50+
ports:
51+
- "8083:80"

0 commit comments

Comments
 (0)