OpenCodeHub
OpenCodeHub is a self-hosted, open-source Git platform meant as an alternative to GitHub and GitLab. Git hosting, pull requests, stacked PRs, merge queues, CI/CD, AI-assisted code review, issues, organizations, webhooks, REST and GraphQL APIs, and a CLI all live in one deployable system. It's built as a modular monolith with optional background workers and CI runners, so it runs on one machine and can still scale horizontally. Git works over HTTP Smart Protocol and SSH. Storage is pluggable (local or S3-compatible), several database backends are supported, CI runs in Docker containers, queues use Redis, and code review can talk to multiple AI providers.
- architecture
- Modular Monolith
- database tables
- 38+
- rest api routes
- 140+
- cli command groups
- 20+
- ai providers
- 10+
- deployment models
- Single-node + Horizontally Scalable
OpenCodeHub is a self-hosted developer platform for teams that want their source control, CI, and code review on their own hardware, without per-seat pricing or vendor lock-in. Git hosting, pull requests, CI/CD, code review, and automation run in one application.
A single instance is enough for a small setup. The same codebase scales horizontally when needed, using shared PostgreSQL, Redis, external object storage, workers, and CI runner pools.
What it does
Git hosting
- Protocols: HTTP Smart Git, Git over SSH
- Repository management: public and private repositories, forks, mirroring, deploy keys, per-repository permissions
- Storage and processing: native Git process execution, Git LFS support
Pull requests
- Review workflows: inline comments, approvals, suggested changes, draft pull requests, required reviews
- Branch management: branch protection, required status checks, stacked pull requests
- Automation: merge queue with speculative builds, developer productivity metrics
CI/CD
The workflow engine is compatible with GitHub Actions. Jobs queue through Redis/BullMQ and run in Docker-based runners with limits on resources and capabilities. Workflows can be triggered by pushes, pull requests, scheduled jobs, or manual dispatch.
AI code review
Review rules and results show up inside the pull request workflow. Supported providers: OpenAI, Anthropic, Google Gemini, Groq, Ollama, OpenRouter, and Mistral.
Issues and project management
- Issues, labels, milestones
- Project boards, Kanban workflows, custom project fields
- A built-in wiki with full revision history
Authentication and security
- Authentication: JWT auth, 2FA/TOTP, SSO/SAML, OAuth with GitHub, Google, and GitLab
- Access control: role-based access control, team permissions, personal access tokens, deploy keys
- Security and auditing: audit logs, rate limiting, secret scanning, encrypted workflow and AI credentials
API and extensibility
- REST API, GraphQL API, OpenAPI specification
- Webhooks, rule-based automations, SDK packages, CLI, pluggable storage adapters
CLI (och)
The och command-line client covers the common workflows:
och auth login
och stack create feature/auth-step-1
och stack submit
och stack sync
och queue list
och queue add <pr-number>
och focus
Architecture
The main application handles the web UI, APIs, Git HTTP operations, and core business logic. SSH, worker, and runner processes are optional, so workloads can be separated as a deployment grows.
Clients
├── Web Browser
├── Git CLI over HTTP
├── Git CLI over SSH
└── OpenCodeHub CLI
↓
OpenCodeHub Platform
├── Astro + React Web UI
├── REST API
├── GraphQL API
├── Git Smart HTTP Server
├── SSH Git Server
├── CI/CD Runner
└── Background Workers
↓
Infrastructure
├── PostgreSQL / SQLite / Turso
├── Redis / BullMQ
└── Local / S3-compatible Storage
Stack
Dedicated modules handle authentication, repositories, pull requests, stacked PRs, merge queues, permissions, webhooks, automation, AI review, pipelines, storage, and validation.
| Component | Technology |
|---|---|
| Frontend UI | Astro SSR, React, Tailwind CSS, Radix UI |
| Database and ORM | Drizzle ORM (PostgreSQL, SQLite, Turso/LibSQL) |
| Async and queueing | Redis, BullMQ |
| CI/CD execution | Docker containers |
| Git operations | Native Git processes |
| Storage layer | Pluggable drivers (local filesystem, S3-compatible object storage) |
The hard part
Technical challenges
Building Git hosting itself
The largest piece of work was implementing an actual Git host instead of a web interface over someone else's. OpenCodeHub speaks Git Smart HTTP and Git over SSH directly, which means dealing with protocol-level behavior: Smart HTTP request and response flows, clone/fetch/push/pull, packfile generation and transfer, SSH public-key authentication, repository authorization, and running Git processes safely. It also has to stay compatible with ordinary Git clients, so nobody needs a custom remote or plugin.
Making a self-hosted architecture scale
The platform had to work for one developer on one server and for a larger organization at the same time. That ruled out a microservices setup. A modular monolith with optional background workers and CI runners covered most of the scaling needs while keeping installation and debugging simple. Stateless application services, shared infrastructure, and horizontal scaling are all possible, but none of them are required to get started.
Stacked pull requests
A normal pull request targets one base branch on its own. Stacks add dependencies between branches, which needs tracking: stack relationships, automatic synchronization, stack-aware merges, dependency validation, and CLI workflows to manage it all. The point is to let people split a large feature into reviewable pieces without slowing down.
Merge queue with CI
The merge queue merges changes in a controlled order and validates queued pull requests with speculative CI runs before they reach the target branch. That involved queue management and prioritization, dependency-aware merge ordering, automatic rebalancing, CI status tracking, failure recovery and rollback, and processing more than one queue at a time. Only validated changes get merged, which keeps the main branch from breaking.
A self-hosted CI/CD engine
Rather than depending on an external CI provider, OpenCodeHub ships its own engine that understands GitHub Actions workflow definitions. Building it meant writing the workflow parser, job scheduling and orchestration, distributed execution queues on Redis and BullMQ, Docker-based isolated execution, log and artifact handling, real-time execution monitoring, and streaming results back to the platform.
Infrastructure choices
The platform is designed to run on whatever infrastructure you already have, so storage and persistence go through adapter interfaces. Databases: PostgreSQL, SQLite, Turso, or another SQL-compatible option. Object storage: MinIO, Cloudflare R2, AWS S3, any S3-compatible service, or the local filesystem. The hard parts were keeping behavior consistent across providers, supporting migrations, and making sure no single vendor became mandatory.
Security
OpenCodeHub holds source code, CI workloads, deployment credentials, and AI provider keys, so security was a design constraint from the start rather than something added later.
Authentication and authorization
- Role-based access control
- JWT authentication
- Personal access tokens
- Repository-level permissions
- Organization and team permissions
- SSH public-key authentication
Application security
- CSRF protection
- Rate limiting
- Request validation
- Session management
- API security controls
Secrets
- Encrypted secret storage
- Credential handling
- Environment isolation
- Secret access controls
Repository security
- Secret scanning
- Repository access auditing
- Protected branches
- Merge restrictions
- Commit verification support
Infrastructure security
- Docker container isolation
- CI runner sandboxing
- Secure process execution
- Resource usage controls
Auditing
- Audit logging
- Authentication event tracking
- Repository activity monitoring
- Administrative action history
Outcome
What shipped
OpenCodeHub started as an idea for source-code hosting and ended up as a full self-hosted developer platform. Instead of stopping at repository management, it covers source control, collaboration, automation, CI/CD, and tooling in one system:
- Git repository hosting over HTTP and SSH
- Pull requests and code review
- Stacked pull request workflows
- Stack-aware merge queues
- GitHub Actions-compatible CI/CD with Docker-based runners
- AI-assisted code review
- Issues and project management
- Organizations and role-based access control
- Webhooks and workflow automation
- REST and GraphQL APIs, plus OpenAPI support
- A dedicated developer CLI
- Pluggable object storage and multiple database backends
- Self-hosted deployment options
Deployment
A single server is enough for individual developers, small teams, internal projects, homelabs, and startups, with minimal operational overhead and the complete platform. Larger organizations can scale horizontally with PostgreSQL for centralized persistence, Redis for queues and coordination, external object storage, dedicated workers, and distributed CI runner pools.
Architecture
The final design is a modular monolith with optional distributed components. The principles behind it: self-hosted first, open standards and interoperability, infrastructure flexibility, horizontal scalability, secure defaults, developer-centric workflows, Git-native operations, and compatibility with cloud or on-premise setups.
What I'd do differently
What I took away
Building OpenCodeHub touched far more than feature work: Git internals, distributed systems, CI orchestration, security, scaling, and developer experience.
Git is more complex than it looks
At the start I thought of Git hosting as repository storage plus a web UI. Supporting it properly meant learning protocol-level behavior, packfile transfers, authentication, repository permissions, and client compatibility.
Developer experience matters as much as features
Plenty of technically correct implementations still created friction for users. Stacked pull requests, merge queues, CI workflows, and repository management all had to be designed around how developers actually work rather than how the system prefers to be driven. The best feature is the one people can use without reading the docs.
Simplicity gets adopted
A fully distributed microservices design looked attractive, but it would have made deployment and operations much harder. The modular monolith gave most of the benefits while keeping install, debugging, and maintenance straightforward. Maintainability came first; scaling came when the need was real.
Self-hosting changes the design decisions
Cloud-native assumptions don't hold when users deploy on a single VPS, a homelab server, a private cloud, or enterprise infrastructure. Deployment models had to stay flexible, infrastructure requirements minimal, storage portable, and database choice open, with clear upgrade paths.
CI/CD is a distributed systems problem
Once I built the workflow engine, it was obvious that CI is mostly scheduling, queues, worker coordination, failure recovery, isolation, log streaming, and resource allocation. Orchestration and fault tolerance matter more than running the commands.
Security has to be in the design from the start
As the platform grew to handle repositories, secrets, SSH keys, CI workloads, and AI integrations, security moved into the architecture: authentication, authorization, secret management, audit logging, secure execution, and repository protection. All of it is easier to design in than to retrofit.
Abstractions prevent lock-in
Supporting several databases and storage providers meant putting clean interfaces between platform logic and infrastructure. That made testing easier, kept deployment flexible, reduced dependence on any one vendor, and leaves room to add providers later.
AI features need context
AI-assisted code review showed that model quality alone doesn't make a feature useful. Results depend on repository context, pull request context, file-level understanding, permission controls, and feedback from developers. Context quality often matters more than model size.
Observability pays for itself
Logs, metrics, audit trails, and execution traces made most production issues much easier to diagnose, and putting them in place early cut debugging time. If a system can't be observed, it can't be operated with any confidence.
Scaling should be earned
Early optimization would have slowed development and added complexity. Most scaling problems were solved more effectively once real usage patterns showed up, so correctness, reliability, and maintainability came first.
Architecture & screenshots