OpenRun: a GitOps deployment platform for internal tools, on Docker or Kubernetes
Deployment platform for code-first internal tools. Deploy web apps declaratively, on a single-node or on Kubernetes, with OIDC/SAML auth and RBAC.
At a glance
- What is it?
- OpenRun is a self-hosted, Apache-2.0 deployment platform that defines apps in config files in Git and runs them on one machine with Docker/Podman or on a Kubernetes cluster. It is aimed at teams who want version-controlled app creation, SSO and per-app database accounts without running a separate build server.
- Who is it for?
- Adopt OpenRun if you are deploying single-container web apps and internal tools and want app creation itself to be version controlled, with the option to move from a single Docker or Podman host to Kubernetes without changing config. Skip it if your app needs multiple containers wired through Docker Compose, since the README states that case is not supported.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What OpenRun is for, and who it fits
Most self-hosted deployment tools let you push code from Git but make you create the app itself by hand, through a CLI or a web form. OpenRun's README draws that line explicitly: with most other solutions, app creation and config updates are manual, and only source code updates flow through Git. OpenRun inverts it. All apps are defined in config files in Git, and `openrun sync schedule` sets up a background sync that creates new apps and updates existing ones as config and code change.
The audience is a team running internal tools: dashboards, small web apps, data scripts wrapped in a UI. The README lists Streamlit, Gradio, FastHTML, NiceGUI, Shiny and Reflex as frameworks with AppSpecs, meaning no Dockerfile and no code changes are needed for those. Anything else that runs in a single container works if you supply a Dockerfile. The README is also clear about the ceiling: apps that require multiple containers using Docker Compose are not supported. Sidecar containers are supported for background workers and companion services, but that is a different shape from a Compose stack.
How the declarative model actually works
The mechanism is a config file per app, held in Git, plus a sync process that reconciles the running state to it. The README points to `examples/utils.star` as the shape of a definition: a couple of lines of config rather than pages of YAML. The `.star` extension and the presence of `github.com/Masterminds/sprig/v3` in go.mod indicate a Starlark-style templating layer over the app spec, which is what keeps definitions short.
Three management paths exist and can be mixed: declarative GitOps, imperative CLI commands such as `openrun app create` and `openrun app update`, and a browser console for apps, bindings, containers, audit events and server config. The README recommends the declarative mode for teams. That recommendation follows from what the mode buys: staged deployment for code and config changes, and atomic all-or-nothing updates across multiple apps. Those two properties are hard to get from a sequence of CLI calls, because a half-applied sequence leaves you reconciling by hand.
Routing is handled by OpenRun itself rather than an external Nginx or Traefik. The README treats that as a deliberate design choice, and it is what makes scale-to-zero and the auth layer possible: the process that terminates the request is also the process that knows whether an app is idle and who is allowed to reach it. Domain-based or path-based routing is supported with automatic TLS, and the go.mod dependencies on `certmagic` and `acmez` line up with that claim.
Installing OpenRun and deploying a first app
The README states that OpenRun runs as a single binary on one server with Docker or Podman, and that the same declarative config can target a Kubernetes cluster. Setup instructions and the quick start live on openrun.dev rather than in the README, so the exact bootstrap command is not reproduced here. What the README and the repository do give is the shape of the workflow once the server is running.
The imperative path is the fastest way to confirm the server, container runtime and routing all work before you commit to Git-driven config. The README names `openrun app create` and `openrun app update` as the commands for managing individual apps directly, and describes this path as useful for trying things out and for scripting.
openrun app createRun it once against a sample repository first. The README does not publish the full flag set, so check the command's own help output before scripting it.
For the declarative path, the README points at `examples/utils.star` as a concrete definition. A definition file is committed to a Git repository, and the sync is registered so OpenRun picks up new apps and config changes from that repository.
openrun sync scheduleThe README describes `openrun sync schedule` as setting up a background sync which creates new apps and updates existing apps as the config and code change in Git. After the sync runs, the app should appear in the management console alongside its container, and any audit events for the change should be visible there too.
If you are deploying a framework with an AppSpec, the README states no Dockerfile and no source changes are required. For anything else, put a Dockerfile in the app source repository and point the config at it. The repository also ships sample apps in `examples/` (including `todo.star`, `streamlit.star` and `hono.star`) that are worth reading before writing your own definition.
Database bindings, SQLite replication and where they stop
Service bindings are the part of OpenRun that goes beyond deployment. A binding provisions an isolated Postgres, MySQL, SQLite or Redis account per app, and the README notes that more databases are supported through binding providers. That matters for internal tools specifically: the common failure mode for a shared internal platform is every app sharing one database user, which makes per-app access control impossible and makes a leaked credential a platform-wide problem.
The SQLite story is more unusual. OpenRun manages SQLite with continuous Litestream replication to S3 and automatic restore, and `github.com/benbjohnson/litestream` appears directly in go.mod. For a small internal tool this removes the usual objection to SQLite in production, which is that a single file on a single host is not durable. It does not make SQLite a distributed database: replication is to object storage, and the README does not describe multi-writer coordination.
The binding system is also where the extension boundary sits. The repository has a `plugins/` directory and go.mod depends on `github.com/hashicorp/go-plugin` plus a separate `github.com/openrundev/openrun/pkg/binding` module. The Makefile comments confirm that `pkg/binding` is a nested module used for binding development, and the build deliberately runs with `GOWORK=off` so a local workspace does not change what gets built or linted. In other words, writing a binding provider is a supported path, but it is module-level Go work, not a config edit.
The limits worth knowing before you commit
The clearest constraint is stated by the project itself: no Docker Compose apps. If your internal tool is a web front end plus a queue worker plus a cron container with shared volumes, OpenRun's single-container-plus-sidecar model may not map onto it cleanly. Sidecars cover background workers and companion services, but the README does not present them as a Compose replacement.
The second limit is that OpenRun is the web server. That is the source of its scale-to-zero and auth behaviour, and it is also a coupling: there is no Nginx or Traefik in front to absorb traffic, terminate TLS independently, or keep serving when OpenRun is restarting. The README does not document what happens to in-flight requests during an OpenRun upgrade. The `cloudflare/tableflip` dependency in go.mod suggests graceful binary replacement is handled, but the README does not describe rollback of a bad config change, and it does not say how far back the sync can revert.
The third is operational scope. A platform that provisions database accounts, replicates SQLite to S3, issues TLS certificates and enforces RBAC has a lot of surface. The README lists audit logs, secrets management, OIDC/SAML and cert-based auth as features, but does not describe a backup or disaster-recovery procedure for OpenRun's own state. The `DR` variable in the Makefile test flags suggests disaster recovery is exercised in the integration suite rather than documented for operators. Treat that as a gap to close yourself before this becomes load-bearing.
How it differs from Coolify, Dokku and CapRover
The README answers this comparison directly, and the answer is worth taking at face value because it is specific. Coolify, Dokku and CapRover are, in OpenRun's framing, imperative: you create and update apps through a CLI or UI, and Git integration covers source code updates. OpenRun makes app creation and config part of the same version-controlled artifact.
The second difference is the Kubernetes path. The README states that most other solutions do not support deployment to Kubernetes, and that OpenRun can move from a single machine with Docker or Podman to a cluster with no config changes. That claim is the one to test first if it is why you are interested, because it is the kind of promise that only holds if your config avoids host-specific assumptions.
The third difference is the built-in web server. Solutions that sit behind Nginx or Traefik inherit a mature, separately upgradable proxy layer. OpenRun trades that for tighter integration: scale-to-zero for app containers and OAuth/SAML/cert auth with RBAC are implemented in the same process. If you already run a hardened ingress layer you are comfortable with, that trade may not be in your favour.
Licence, maintenance and upgrade cost
OpenRun is Apache-2.0, and the licence headers in go.mod and the Makefile carry a ClaceIO, LLC copyright line with an SPDX identifier. Apache-2.0 is permissive and includes an explicit patent grant, which is usually what matters for internal platform software. It also means you can fork and modify without a copyleft obligation. Nothing here is legal advice; if you redistribute OpenRun or a modified binding provider, read the licence text in the repository.
The project is not archived, and the last push was on 2026-08-26, the same day as the v0.19.2 release. v0.19.0 and v0.19.1 both landed on 2026-08-21, so the release cadence around that date was tight. Version numbers in the 0.19.x range mean the project does not present a 1.0 stability promise, and the README's roadmap section is the place to check what is still planned.
Upgrade cost is dominated by the sync model rather than the binary. Because app definitions live in Git, a config change is reviewed and reverted the same way code is, which is the point. The binary itself is Go, built through the repository Makefile, and the integration suite is driven by `tests/run_cli_tests.sh` with flags for container tooling and for Postgres, MySQL, Redis, SeaweedFS and Kubernetes registries. Running that suite against your own environment is the honest way to price an upgrade.
Editorial conclusion
Adopt OpenRun if you are deploying single-container web apps and internal tools and want app creation itself to be version controlled, with the option to move from a single Docker or Podman host to Kubernetes without changing config. Skip it if your app needs multiple containers wired through Docker Compose, since the README states that case is not supported. Before committing, verify three things in your own environment: that your framework has an AppSpec or that you are prepared to ship a Dockerfile, that your Git provider is reachable from the OpenRun server for sync, and that the database binding providers you need exist for your engine.
Frequently asked questions
What is OpenRun?
OpenRun is an Apache-2.0 licensed, self-hosted GitOps platform for deploying web apps and internal tools. It runs as a single binary on one server with Docker or Podman, or deploys apps onto a Kubernetes cluster using the same declarative config, and it adds OAuth/OIDC/SAML auth, RBAC, database service bindings and scale-to-zero for idle apps.
Does OpenRun support apps that need multiple containers with Docker Compose?
No. The README states that OpenRun does not support apps which require multiple containers using Docker Compose. It supports a single container per app with optional sidecar containers for background workers and companion services.
How does OpenRun compare to Coolify, Dokku or CapRover?
The README lists three differences: OpenRun is declarative, so app creation and config changes happen by updating a config file in Git rather than through a CLI or UI; OpenRun can deploy to Kubernetes as well as a single Docker or Podman host; and OpenRun is itself the web server, so it does not depend on Nginx or Traefik and can implement scale-to-zero and OAuth/SAML/cert auth with RBAC.
Do I need a Dockerfile to deploy an app with OpenRun?
It depends on the framework. The README states that for frameworks which have an AppSpec, such as Streamlit, Gradio, FastHTML, NiceGUI, Shiny and Reflex, no Dockerfile and no source code changes are required. For frameworks without an AppSpec, a Dockerfile must be present in the app source repository.
How do I manage apps in OpenRun without Git?
The README documents an imperative path using CLI commands such as `openrun app create` and `openrun app update`, described as useful for trying things out and for scripting. A browser-based management console is also available for creating and managing apps, services, bindings and secrets. The README recommends the declarative GitOps mode for teams.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/openrundev-openrun)