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)
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.
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.
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.
| 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 |
- Kubernetes cluster (k3s recommended, any distribution works)
- Helm
kubectl,curl,jq,git- Wildcard DNS (
*.yourdomain.com) pointing to your cluster's ingress IP
# 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# 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- 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) - All other services use Forgejo SSO -- click "Sign in with Forgejo"
- Run
make urlsto see all service URLs
Create a new repository from system/template on Forgejo, or use the CLI:
op app create --org myorg --name myappThe 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}.
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
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.
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.
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: ""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
open-platform.yamldefines your platform (domain, admin, TLS, optional features)make deployinstalls Flux controllers and the platform Helm chart- The Helm chart renders Flux CRDs (HelmReleases, Kustomizations) that Flux reconciles in dependency order
- A bootstrap Job configures OAuth2 between services, sets up the system org, and seeds repos
- Flux manages all releases -- the platform is self-managing from here
- Push changes to
system/open-platformon Forgejo and Flux reconciles within a minute
| 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 |
AGPL-3.0 -- see LICENSE.