Skip to content
Closed
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
44 changes: 44 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Git
.git
.gitignore

# Documentation
README.md
docs/

# Environment files
.env
.env.local
.env.example

# Build artifacts
bin/
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test artifacts
*.test
*.out
coverage.*
*.coverprofile
profile.cov

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Logs
*.log

# Development
scripts/dev.sh
21 changes: 21 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Server Configuration
SERVER_HOST=localhost
SERVER_PORT=8080
SERVER_ENV=development

# Database Configuration
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=your_password_here
DB_NAME=voidrunner
DB_SSL_MODE=disable

# Logger Configuration
LOG_LEVEL=info
LOG_FORMAT=json

# CORS Configuration
CORS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173
CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,OPTIONS
CORS_ALLOWED_HEADERS=Content-Type,Authorization,X-Request-ID
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
*.so
*.dylib

# Build output
bin/

# Test binary, built with `go test -c`
*.test

Expand Down
52 changes: 52 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Build stage
FROM golang:1.24-alpine AS builder

# Install dependencies
RUN apk --no-cache add ca-certificates git

# Set working directory
WORKDIR /app

# Copy go mod files
COPY go.mod go.sum ./

# Download dependencies
RUN go mod download

# Copy source code
COPY . .

# Build the application
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o api cmd/api/main.go

# Final stage
FROM alpine:latest

# Install ca-certificates and curl for health checks
RUN apk --no-cache add ca-certificates curl

# Create non-root user
RUN addgroup -g 1001 -S voidrunner && \
adduser -u 1001 -S voidrunner -G voidrunner

# Set working directory
WORKDIR /app

# Copy binary from builder stage
COPY --from=builder /app/api .

# Change ownership to non-root user
RUN chown -R voidrunner:voidrunner /app

# Switch to non-root user
USER voidrunner

# Expose port
EXPOSE 8080

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1

# Run the application
CMD ["./api"]
134 changes: 132 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,132 @@
# voidrunner
The LLM-powered distributed task execution platform
# VoidRunner

The LLM-powered distributed task execution platform built with Go and Kubernetes.

## Overview

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.

## Features

- **Secure Execution**: Container-based task execution with gVisor security
- **RESTful API**: Clean HTTP API with structured logging and monitoring
- **Kubernetes Native**: Designed for cloud-native deployments
- **Authentication**: JWT-based authentication system
- **Monitoring**: Built-in health checks and observability

## Quick Start

### Prerequisites

- Go 1.24+ installed
- PostgreSQL (for future database operations)
- Docker (for containerization)

### Setup

1. **Clone the repository**
```bash
git clone https://github.com/voidrunnerhq/voidrunner.git
cd voidrunner
```

2. **Install dependencies**
```bash
go mod download
```

3. **Configure environment**
```bash
cp .env.example .env
# Edit .env with your configuration
```

4. **Run the development server**
```bash
go run cmd/api/main.go
```

The server will start on `http://localhost:8080` by default.

### API Endpoints

- `GET /health` - Health check endpoint
- `GET /ready` - Readiness check endpoint
- `GET /api/v1/ping` - Simple ping endpoint

### Testing

Run all tests:
```bash
go test ./...
```

Run tests with coverage:
```bash
go test ./... -cover
```

Run specific test suite:
```bash
go test ./internal/api/handlers/... -v
```

### Build

Build the application:
```bash
go build -o bin/api cmd/api/main.go
```

Run the binary:
```bash
./bin/api
```

## Architecture

VoidRunner follows the standard Go project layout:

```
voidrunner/
├── cmd/ # Application entrypoints
│ └── api/ # API server main
├── internal/ # Private application code
│ ├── api/ # API handlers and routes
│ │ ├── handlers/ # HTTP handlers
│ │ ├── middleware/ # HTTP middleware
│ │ └── routes/ # Route definitions
│ ├── config/ # Configuration management
│ ├── database/ # Database layer
│ └── models/ # Data models
├── pkg/ # Public libraries
│ ├── logger/ # Structured logging
│ ├── metrics/ # Prometheus metrics
│ └── utils/ # Shared utilities
├── migrations/ # Database migrations
├── scripts/ # Build and deployment scripts
└── docs/ # Documentation
```

## Configuration

The application uses environment variables for configuration. See `.env.example` for available options:

- `SERVER_HOST`: Server bind address (default: localhost)
- `SERVER_PORT`: Server port (default: 8080)
- `SERVER_ENV`: Environment (development/production)
- `LOG_LEVEL`: Logging level (debug/info/warn/error)
- `LOG_FORMAT`: Log format (json/text)
- `CORS_ALLOWED_ORIGINS`: Comma-separated list of allowed origins

## Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
68 changes: 68 additions & 0 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package main

import (
"context"
"errors"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"time"

"github.com/gin-gonic/gin"
"github.com/voidrunnerhq/voidrunner/internal/api/routes"
"github.com/voidrunnerhq/voidrunner/internal/config"
"github.com/voidrunnerhq/voidrunner/pkg/logger"
)

func main() {
cfg, err := config.Load()
if err != nil {
fmt.Printf("Failed to load configuration: %v\n", err)
os.Exit(1)
}

log := logger.New(cfg.Logger.Level, cfg.Logger.Format)

if cfg.IsProduction() {
gin.SetMode(gin.ReleaseMode)
}

router := gin.New()
routes.Setup(router, cfg, log)

srv := &http.Server{
Addr: fmt.Sprintf("%s:%s", cfg.Server.Host, cfg.Server.Port),
Handler: router,
}

go func() {
log.Info("starting server",
"host", cfg.Server.Host,
"port", cfg.Server.Port,
"env", cfg.Server.Env,
)

if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Error("server failed to start", "error", err)
os.Exit(1)
}
}()

quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit

log.Info("shutting down server...")

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

if err := srv.Shutdown(ctx); err != nil {
log.Error("server forced to shutdown", "error", err)
os.Exit(1)
}

log.Info("server exited")
}
41 changes: 41 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module github.com/voidrunnerhq/voidrunner

go 1.24.4

require (
github.com/gin-contrib/cors v1.7.6
github.com/gin-gonic/gin v1.10.1
github.com/google/uuid v1.6.0
github.com/joho/godotenv v1.5.1
github.com/stretchr/testify v1.10.0
)

require (
github.com/bytedance/sonic v1.13.3 // indirect
github.com/bytedance/sonic/loader v0.2.4 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
github.com/gin-contrib/sse v1.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.26.0 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.0 // indirect
golang.org/x/arch v0.18.0 // indirect
golang.org/x/crypto v0.39.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.26.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading
Loading