Skip to content

Commit 9b5dd85

Browse files
starbopsclaude
andcommitted
feat: implement Go project foundation and API infrastructure
- Initialize Go module with Gin web framework - Add structured logging with slog and request correlation - Implement configuration management with environment variables - Create health check and readiness endpoints - Set up CORS, security headers, and error handling middleware - Add comprehensive test suite with 65-89% coverage - Configure Docker containerization with security best practices - Update documentation with setup and development instructions Implements #2 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 990698e commit 9b5dd85

File tree

22 files changed

+1316
-2
lines changed

22 files changed

+1316
-2
lines changed

.dockerignore

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Git
2+
.git
3+
.gitignore
4+
5+
# Documentation
6+
README.md
7+
docs/
8+
9+
# Environment files
10+
.env
11+
.env.local
12+
.env.example
13+
14+
# Build artifacts
15+
bin/
16+
*.exe
17+
*.exe~
18+
*.dll
19+
*.so
20+
*.dylib
21+
22+
# Test artifacts
23+
*.test
24+
*.out
25+
coverage.*
26+
*.coverprofile
27+
profile.cov
28+
29+
# IDE
30+
.vscode/
31+
.idea/
32+
*.swp
33+
*.swo
34+
*~
35+
36+
# OS
37+
.DS_Store
38+
Thumbs.db
39+
40+
# Logs
41+
*.log
42+
43+
# Development
44+
scripts/dev.sh

.env.example

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Server Configuration
2+
SERVER_HOST=localhost
3+
SERVER_PORT=8080
4+
SERVER_ENV=development
5+
6+
# Database Configuration
7+
DB_HOST=localhost
8+
DB_PORT=5432
9+
DB_USER=postgres
10+
DB_PASSWORD=your_password_here
11+
DB_NAME=voidrunner
12+
DB_SSL_MODE=disable
13+
14+
# Logger Configuration
15+
LOG_LEVEL=info
16+
LOG_FORMAT=json
17+
18+
# CORS Configuration
19+
CORS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173
20+
CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,OPTIONS
21+
CORS_ALLOWED_HEADERS=Content-Type,Authorization,X-Request-ID

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
*.so
99
*.dylib
1010

11+
# Build output
12+
bin/
13+
1114
# Test binary, built with `go test -c`
1215
*.test
1316

Dockerfile

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Build stage
2+
FROM golang:1.24-alpine AS builder
3+
4+
# Install dependencies
5+
RUN apk --no-cache add ca-certificates git
6+
7+
# Set working directory
8+
WORKDIR /app
9+
10+
# Copy go mod files
11+
COPY go.mod go.sum ./
12+
13+
# Download dependencies
14+
RUN go mod download
15+
16+
# Copy source code
17+
COPY . .
18+
19+
# Build the application
20+
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o api cmd/api/main.go
21+
22+
# Final stage
23+
FROM alpine:latest
24+
25+
# Install ca-certificates and curl for health checks
26+
RUN apk --no-cache add ca-certificates curl
27+
28+
# Create non-root user
29+
RUN addgroup -g 1001 -S voidrunner && \
30+
adduser -u 1001 -S voidrunner -G voidrunner
31+
32+
# Set working directory
33+
WORKDIR /app
34+
35+
# Copy binary from builder stage
36+
COPY --from=builder /app/api .
37+
38+
# Change ownership to non-root user
39+
RUN chown -R voidrunner:voidrunner /app
40+
41+
# Switch to non-root user
42+
USER voidrunner
43+
44+
# Expose port
45+
EXPOSE 8080
46+
47+
# Health check
48+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
49+
CMD curl -f http://localhost:8080/health || exit 1
50+
51+
# Run the application
52+
CMD ["./api"]

README.md

Lines changed: 132 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,132 @@
1-
# voidrunner
2-
The LLM-powered distributed task execution platform
1+
# VoidRunner
2+
3+
The LLM-powered distributed task execution platform built with Go and Kubernetes.
4+
5+
## Overview
6+
7+
VoidRunner is a Kubernetes-based distributed task execution platform that provides secure, scalable code execution in containerized environments. The platform is designed with security-first principles and follows microservices architecture.
8+
9+
## Features
10+
11+
- **Secure Execution**: Container-based task execution with gVisor security
12+
- **RESTful API**: Clean HTTP API with structured logging and monitoring
13+
- **Kubernetes Native**: Designed for cloud-native deployments
14+
- **Authentication**: JWT-based authentication system
15+
- **Monitoring**: Built-in health checks and observability
16+
17+
## Quick Start
18+
19+
### Prerequisites
20+
21+
- Go 1.24+ installed
22+
- PostgreSQL (for future database operations)
23+
- Docker (for containerization)
24+
25+
### Setup
26+
27+
1. **Clone the repository**
28+
```bash
29+
git clone https://github.com/voidrunnerhq/voidrunner.git
30+
cd voidrunner
31+
```
32+
33+
2. **Install dependencies**
34+
```bash
35+
go mod download
36+
```
37+
38+
3. **Configure environment**
39+
```bash
40+
cp .env.example .env
41+
# Edit .env with your configuration
42+
```
43+
44+
4. **Run the development server**
45+
```bash
46+
go run cmd/api/main.go
47+
```
48+
49+
The server will start on `http://localhost:8080` by default.
50+
51+
### API Endpoints
52+
53+
- `GET /health` - Health check endpoint
54+
- `GET /ready` - Readiness check endpoint
55+
- `GET /api/v1/ping` - Simple ping endpoint
56+
57+
### Testing
58+
59+
Run all tests:
60+
```bash
61+
go test ./...
62+
```
63+
64+
Run tests with coverage:
65+
```bash
66+
go test ./... -cover
67+
```
68+
69+
Run specific test suite:
70+
```bash
71+
go test ./internal/api/handlers/... -v
72+
```
73+
74+
### Build
75+
76+
Build the application:
77+
```bash
78+
go build -o bin/api cmd/api/main.go
79+
```
80+
81+
Run the binary:
82+
```bash
83+
./bin/api
84+
```
85+
86+
## Architecture
87+
88+
VoidRunner follows the standard Go project layout:
89+
90+
```
91+
voidrunner/
92+
├── cmd/ # Application entrypoints
93+
│ └── api/ # API server main
94+
├── internal/ # Private application code
95+
│ ├── api/ # API handlers and routes
96+
│ │ ├── handlers/ # HTTP handlers
97+
│ │ ├── middleware/ # HTTP middleware
98+
│ │ └── routes/ # Route definitions
99+
│ ├── config/ # Configuration management
100+
│ ├── database/ # Database layer
101+
│ └── models/ # Data models
102+
├── pkg/ # Public libraries
103+
│ ├── logger/ # Structured logging
104+
│ ├── metrics/ # Prometheus metrics
105+
│ └── utils/ # Shared utilities
106+
├── migrations/ # Database migrations
107+
├── scripts/ # Build and deployment scripts
108+
└── docs/ # Documentation
109+
```
110+
111+
## Configuration
112+
113+
The application uses environment variables for configuration. See `.env.example` for available options:
114+
115+
- `SERVER_HOST`: Server bind address (default: localhost)
116+
- `SERVER_PORT`: Server port (default: 8080)
117+
- `SERVER_ENV`: Environment (development/production)
118+
- `LOG_LEVEL`: Logging level (debug/info/warn/error)
119+
- `LOG_FORMAT`: Log format (json/text)
120+
- `CORS_ALLOWED_ORIGINS`: Comma-separated list of allowed origins
121+
122+
## Contributing
123+
124+
1. Fork the repository
125+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
126+
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
127+
4. Push to the branch (`git push origin feature/amazing-feature`)
128+
5. Open a Pull Request
129+
130+
## License
131+
132+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

cmd/api/main.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"net/http"
8+
"os"
9+
"os/signal"
10+
"syscall"
11+
"time"
12+
13+
"github.com/gin-gonic/gin"
14+
"github.com/voidrunnerhq/voidrunner/internal/api/routes"
15+
"github.com/voidrunnerhq/voidrunner/internal/config"
16+
"github.com/voidrunnerhq/voidrunner/pkg/logger"
17+
)
18+
19+
func main() {
20+
cfg, err := config.Load()
21+
if err != nil {
22+
fmt.Printf("Failed to load configuration: %v\n", err)
23+
os.Exit(1)
24+
}
25+
26+
log := logger.New(cfg.Logger.Level, cfg.Logger.Format)
27+
28+
if cfg.IsProduction() {
29+
gin.SetMode(gin.ReleaseMode)
30+
}
31+
32+
router := gin.New()
33+
routes.Setup(router, cfg, log)
34+
35+
srv := &http.Server{
36+
Addr: fmt.Sprintf("%s:%s", cfg.Server.Host, cfg.Server.Port),
37+
Handler: router,
38+
}
39+
40+
go func() {
41+
log.Info("starting server",
42+
"host", cfg.Server.Host,
43+
"port", cfg.Server.Port,
44+
"env", cfg.Server.Env,
45+
)
46+
47+
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
48+
log.Error("server failed to start", "error", err)
49+
os.Exit(1)
50+
}
51+
}()
52+
53+
quit := make(chan os.Signal, 1)
54+
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
55+
<-quit
56+
57+
log.Info("shutting down server...")
58+
59+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
60+
defer cancel()
61+
62+
if err := srv.Shutdown(ctx); err != nil {
63+
log.Error("server forced to shutdown", "error", err)
64+
os.Exit(1)
65+
}
66+
67+
log.Info("server exited")
68+
}

go.mod

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module github.com/voidrunnerhq/voidrunner
2+
3+
go 1.24.4
4+
5+
require (
6+
github.com/gin-contrib/cors v1.7.6
7+
github.com/gin-gonic/gin v1.10.1
8+
github.com/google/uuid v1.6.0
9+
github.com/joho/godotenv v1.5.1
10+
github.com/stretchr/testify v1.10.0
11+
)
12+
13+
require (
14+
github.com/bytedance/sonic v1.13.3 // indirect
15+
github.com/bytedance/sonic/loader v0.2.4 // indirect
16+
github.com/cloudwego/base64x v0.1.5 // indirect
17+
github.com/davecgh/go-spew v1.1.1 // indirect
18+
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
19+
github.com/gin-contrib/sse v1.1.0 // indirect
20+
github.com/go-playground/locales v0.14.1 // indirect
21+
github.com/go-playground/universal-translator v0.18.1 // indirect
22+
github.com/go-playground/validator/v10 v10.26.0 // indirect
23+
github.com/goccy/go-json v0.10.5 // indirect
24+
github.com/json-iterator/go v1.1.12 // indirect
25+
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
26+
github.com/leodido/go-urn v1.4.0 // indirect
27+
github.com/mattn/go-isatty v0.0.20 // indirect
28+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
29+
github.com/modern-go/reflect2 v1.0.2 // indirect
30+
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
31+
github.com/pmezard/go-difflib v1.0.0 // indirect
32+
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
33+
github.com/ugorji/go/codec v1.3.0 // indirect
34+
golang.org/x/arch v0.18.0 // indirect
35+
golang.org/x/crypto v0.39.0 // indirect
36+
golang.org/x/net v0.41.0 // indirect
37+
golang.org/x/sys v0.33.0 // indirect
38+
golang.org/x/text v0.26.0 // indirect
39+
google.golang.org/protobuf v1.36.6 // indirect
40+
gopkg.in/yaml.v3 v3.0.1 // indirect
41+
)

0 commit comments

Comments
 (0)