Skip to content

Trevato/open-platform

Repository files navigation

Open Platform

Self-hosted developer platform. One command deploys Git hosting, CI/CD, object storage, video conferencing, team messaging, a management console, and PostgreSQL -- all authenticated through a single identity provider and served on one wildcard domain.

*.yourdomain.com
  forgejo.   -- Git, packages, container registry, SSO
  ci.        -- CI/CD pipelines
  minio.     -- Object storage console
  s3.        -- S3-compatible API
  console.   -- Management dashboard
  api.       -- REST API + MCP server (43 tools for AI agents)
  meet.      -- Video conferencing (Jitsi Meet)
  chat.      -- Team messaging (Zulip)
  mail.      -- Email testing (Mailpit, dev mode)
  {app}.     -- Your apps (push-to-deploy from template)

Why

Setting up a modern dev environment means stitching together a dozen SaaS products, managing separate auth for each, and hoping they integrate. Open Platform replaces all of that with a single deploy that just works -- self-hosted, self-managing, and designed for teams that want to own their infrastructure.

After bootstrap, Flux GitOps takes over. Push to the platform repo on Forgejo and changes reconcile automatically. No manual Helm commands in steady state.

Features

One-command deploy. make deploy bootstraps everything from a single open-platform.yaml config file -- generates secrets, installs services, configures OAuth2 between them, and hands off to Flux.

App template. Create a new repo from the built-in template and get a production-ready Next.js 15 app with PostgreSQL, S3 storage, Forgejo OAuth2, and four CI workflows. Push to main and it deploys. Open a PR and it gets its own isolated preview environment.

PR preview environments. Every pull request gets a dedicated namespace, database, and S3 bucket. Seed data is applied automatically. OAuth2-Proxy requires Forgejo login to access. Closing the PR cleans up everything.

MCP Server. 43 tools across 10 categories give AI agents programmatic access to repos, issues, PRs, pipelines, and apps. Streamable HTTP transport with session management.

Multi-domain. Assign different domains to different orgs. Apps deploy on their org's domain. Cloudflare Tunnel routes are configured automatically for each domain.

CLI. The op command handles everything: apps, PRs, issues, pipelines, users. Authenticates via Forgejo personal access token.

Architecture

Browser --> Traefik (ingress, wildcard DNS)
              |-- forgejo    --> Forgejo (git, packages, OIDC provider)
              |-- ci         --> Woodpecker (CI/CD, K8s-native backend)
              |-- minio / s3 --> MinIO (S3-compatible object storage)
              |-- console    --> Console (management dashboard)
              |-- api        --> Platform API (REST + MCP, 43 AI tools)
              |-- meet       --> Jitsi Meet (video conferencing)
              |-- chat       --> Zulip (team messaging)
              |-- mail       --> Mailpit (dev email)
              |-- {apps}     --> Apps (from template, push-to-deploy)

Flux (GitOps) --> system/open-platform on Forgejo --> reconciles all services
Woodpecker CI --> builds and deploys apps per push
PostgreSQL    --> CNPG-managed cluster (shared infrastructure)

All services authenticate through Forgejo as the single OIDC/OAuth2 identity provider. Sign in once, access everything.

Services

Service Domain Role
Forgejo forgejo.{domain} Git, packages, container registry, SSO provider
Woodpecker ci.{domain} CI/CD with K8s-native pipeline backend
MinIO minio.{domain} / s3.{domain} S3-compatible object storage
Console console.{domain} Platform management dashboard
Platform API api.{domain} REST + MCP (43 tools)
Jitsi Meet meet.{domain} Video conferencing (OIDC via Forgejo)
Zulip chat.{domain} Team messaging (OIDC via Forgejo)
Mailpit mail.{domain} Dev email catch-all (disabled in production)
OAuth2-Proxy oauth2.{domain} Auth gate for PR preview environments
PostgreSQL internal CNPG-managed database cluster
Flux internal GitOps -- self-managing after bootstrap

Quick Start

Prerequisites

  • Kubernetes cluster (k3s recommended, any distribution works)
  • Helm
  • kubectl, curl, jq, git
  • Wildcard DNS (*.yourdomain.com) pointing to your cluster's ingress IP

Linux (bare metal or VM)

# Install k3s (if needed)
curl -sfL https://get.k3s.io | sh -

# Clone and configure
git clone https://github.com/trevato/open-platform.git
cd open-platform
cp open-platform.yaml.example open-platform.yaml
# Edit: set domain, admin email, tls.mode (letsencrypt recommended)

# Deploy
make deploy

macOS (Colima -- for local development)

# Start a k3s-compatible VM
colima start op --kubernetes --cpu 4 --memory 8 --disk 50 \
  --runtime containerd --network-address

# Note the VM IP from `colima list` (e.g., 192.168.64.4)
# Configure DNS: resolve *.dev.test to the VM IP (dnsmasq or /etc/hosts)

# Clone and configure
git clone https://github.com/trevato/open-platform.git
cd open-platform
cp open-platform.yaml.example open-platform.yaml
# Edit: set domain: dev.test, tls.mode: selfsigned

# Deploy
make deploy

# Trust the self-signed CA
sudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain certs/ca.crt

After Deploy

  1. Open https://forgejo.{domain} and sign in with the admin credentials (kubectl get secret forgejo-admin-credentials -n forgejo -o jsonpath='{.data.password}' | base64 -d)
  2. All other services use Forgejo SSO -- click "Sign in with Forgejo"
  3. Run make urls to see all service URLs

Creating Apps

Create a new repository from system/template on Forgejo, or use the CLI:

op app create --org myorg --name myapp

The template includes:

  • Next.js 15 with App Router
  • PostgreSQL database (provisioned per app)
  • S3/MinIO storage (bucket per app)
  • Forgejo OAuth2 via better-auth
  • 4 CI workflows: deploy (main), preview (PR), preview-cleanup (PR close), reset (manual)

Push to main and Woodpecker builds, provisions infrastructure, and deploys. The app is live at https://{appname}.{domain}.

PR Preview Environments

Open a pull request and an isolated preview auto-deploys:

  • Dedicated namespace, database, and S3 bucket
  • URL: https://pr-{N}-{repo}.{domain}
  • Protected by OAuth2-Proxy (requires Forgejo login)
  • Seed data applied automatically
  • Cleaned up when the PR closes

CLI

The op CLI authenticates with a Forgejo personal access token:

op login https://api.{domain} --token <your-pat>

Selected commands:

op status                           Platform health check
op whoami                           Current user info

op app list                         List deployed apps
op app create --org O --name N      Create app from template
op app deploy org/repo              Trigger deploy pipeline

op pr list org/repo                 List pull requests
op pr create org/repo -t "Title"    Create a PR
op pr merge org/repo 1              Merge PR #1

op issue list org/repo              List issues
op issue create org/repo -t "Bug"   Create an issue

op pipeline list org/repo           List CI pipelines
op pipeline logs org/repo 42        View pipeline logs

See docs/cli.md for the full command reference.

MCP Server

The MCP server gives AI agents full access to the platform through 43 tools. Add to your MCP client config:

{
  "mcpServers": {
    "open-platform": {
      "type": "streamable-http",
      "url": "https://api.{domain}/mcp",
      "headers": {
        "Authorization": "Bearer <forgejo-pat>"
      }
    }
  }
}

Tool categories: orgs (2), repos (5), PRs (7), issues (7), branches (3), files (3), pipelines (4), apps (6), users (1), platform (5).

See docs/mcp.md for the full tool catalog.

Configuration

open-platform.yaml is the single source of truth. Copy the example and edit:

domain: myplatform.example.com

admin:
  username: opadmin
  email: admin@example.com

tls:
  mode: letsencrypt # letsencrypt | selfsigned | cloudflare


# Optional: additional domains for multi-org deployments
# extraDomains:
#   - name: client-a.com
#     tls:
#       mode: cloudflare
#   - name: client-b.com
#     tls:
#       mode: cloudflare

# Optional: Cloudflare Tunnel (when tls.mode is cloudflare)
# cloudflare:
#   accountTag: ""
#   tunnelId: ""
#   tunnelSecret: ""

Makefile Targets

make deploy      Install Flux + platform Helm chart (idempotent)
make upgrade     Upgrade the platform chart
make status      Check Flux HelmRelease reconciliation
make template    Render chart templates (dry run)
make lint        Lint the Helm chart
make urls        Show all service URLs
make teardown    Destroy all resources (requires confirmation)
make test-smoke  Run smoke tests (curl-based)
make test-e2e    Run Playwright E2E tests

How It Works

  1. open-platform.yaml defines your platform (domain, admin, TLS, optional features)
  2. make deploy installs Flux controllers and the platform Helm chart
  3. The Helm chart renders Flux CRDs (HelmReleases, Kustomizations) that Flux reconciles in dependency order
  4. A bootstrap Job configures OAuth2 between services, sets up the system org, and seeds repos
  5. Flux manages all releases -- the platform is self-managing from here
  6. Push changes to system/open-platform on Forgejo and Flux reconciles within a minute

Documentation

Document Description
Getting Started Install, deploy, first login, create an app
REST API Endpoint reference, auth, error format
CLI Full command reference for op
MCP Server Tool catalog for AI agents
Permissions Auth model and roles
Services Per-service config, secrets, env vars
Known Issues Implementation notes and debugging

License

AGPL-3.0 -- see LICENSE.

About

complete software development infrastructure

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors