DEV Community

Cover image for I Built a Small Self-Hosted Runner for AI Coding Tasks
Tomáš Grasl
Tomáš Grasl

Posted on

I Built a Small Self-Hosted Runner for AI Coding Tasks

I built a small runner for self-hosted AI coding. It's similar to Claude Code but isolated in Docker and fully self-hosted.

I actually like what Anthropic did with Claude Code on the web — for small tasks it works fine. But I needed something I could hook up not just to GitHub but also to GitLab. So I said to myself: I'll just write it. And for this kind of thing, Go is the best fit.

What It Does

CodeForge receives task requests via REST API, clones your repository, runs an AI CLI tool (Claude Code) against it, streams progress via Redis Pub/Sub, and optionally creates pull requests. It supports multi-turn conversations, webhook callbacks, and workspace lifecycle management.

Client                  CodeForge                          AI CLI
  │                        │                                 │
  │  POST /api/v1/tasks    │                                 │
  ├───────────────────────▶│                                 │
  │         201 {id}       │                                 │
  │◀───────────────────────┤                                 │
  │                        │  git clone ──▶ run CLI          │
  │                        ├────────────────────────────────▶│
  │    Redis Pub/Sub       │         stream-json events      │
  │◀ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┤◀────────────────────────────────┤
  │                        │                                 │
  │  GET /tasks/{id}       │           result + diff         │
  ├───────────────────────▶│◀────────────────────────────────┤
  │     200 {result}       │                                 │
  │◀───────────────────────┤                                 │
  │                        │                                 │
  │  POST /tasks/{id}/     │                                 │
  │       create-pr        │  git push ──▶ GitHub/GitLab API │
  ├───────────────────────▶├─────────────────────────────────▶
  │     200 {pr_url}       │                                 │
  │◀───────────────────────┤                                 │
Enter fullscreen mode Exit fullscreen mode

You POST a task with a repo URL and a prompt. CodeForge clones the repo, spawns the AI CLI, streams progress events through Redis Pub/Sub, and when it's done, you can tell it to create a pull request. That's it.

Quick Start

# Start the server (requires Docker + docker-compose)
docker compose -f deployments/docker-compose.yaml \
  -f deployments/docker-compose.dev.yaml up --build

# Create a task
curl -X POST http://localhost:8080/api/v1/tasks \
  -H "Authorization: Bearer dev-token" \
  -H "Content-Type: application/json" \
  -d '{
    "repo_url": "https://github.com/user/repo.git",
    "access_token": "ghp_your_token",
    "prompt": "Fix the failing tests in the auth module"
  }'

# Check status
curl http://localhost:8080/api/v1/tasks/{id} \
  -H "Authorization: Bearer dev-token"
Enter fullscreen mode Exit fullscreen mode

If you have Task installed, just run task dev instead of the docker compose command.

Why Go?

I considered Node.js (my second language after PHP) and Rust, but Go hit the sweet spot:

  • Single binary deployment — no runtime dependencies, no node_modules, just copy and run
  • Excellent concurrency — goroutines handle multiple simultaneous tasks without callback gymnastics
  • Low memory footprint — the service itself uses ~15MB RAM, leaving resources for the actual AI CLI
  • Fast startup — critical for containerized environments where pods come and go
  • Battle-tested HTTP/Redis librariesnet/http, go-redis, chi router — mature, stable, boring (in a good way)

Real-World Use Cases

Here are some ways I'm using CodeForge (or planning to):

Automated issue fixing — GitHub/GitLab webhook fires when an issue gets the ai-fix label. A small middleware translates it into a CodeForge task. Minutes later, a PR appears.

Nightly code maintenance — Cron job that runs prompts like "update deprecated API calls" or "improve error messages" across multiple repos.

Non-developer requests — Product managers submit tasks through a simple form: "Add a loading spinner to the dashboard page." CodeForge handles the rest.

Code review bot — After a human creates a PR, trigger CodeForge to review it with a separate AI instance and post comments.

What's on the Roadmap

CodeForge currently uses Claude Code as its AI backend, but the architecture is designed to be CLI-agnostic. Here's what's coming:

  • Multi-CLI support — runners for OpenCode, Codex, and other AI coding CLIs
  • Task sessions — cross-task memory so the AI remembers context from previous tasks on the same repo
  • Automated code review — a second AI pass reviews changes before creating a PR
  • Subscription & multi-user auth — per-user API keys and usage tracking

Try It Out

The repo is at github.com/freema/codeforge. I'd love feedback — especially on the API design and the multi-CLI architecture that's coming next.

If you have questions or ideas, open an issue or find me on GitHub.

Top comments (0)