# Compartment: a self-hosted Kubernetes deployment system for internal tools

> Compartment is a CLI-first, repository-first deployment layer that installs into an existing Kubernetes cluster or provisions a managed single-node host. It is aimed at teams running small internal apps on infrastructure they control, and it is still pre-1.0.

**compartmentdev/compartment** — Compartment is a self-hosted deployment system for small software on infrastructure your team controls.

- Repository: https://github.com/compartmentdev/compartment
- Website: https://compartment.dev
- Stars: 206 · Forks: 5
- Language: TypeScript
- License: Apache-2.0
- Published: 2026-08-04 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/compartmentdev-compartment

## The problem Compartment targets: small software with nowhere stable to run

A script becomes an internal tool. A worker becomes something three people depend on. An AI-generated app turns out to be useful enough that it needs an owner, a URL, and a permission model. Compartment is built for that moment. Its README frames the audience as teams whose software "started as a script, internal app, worker, or AI-generated tool" and now needs a stable place to run.

The alternative it is arguing against is the informal path: ad hoc links, manual handoffs, unclear ownership, and permissions granted by whoever happens to have cluster access. Compartment puts a control plane in front of that: URLs, an access model, deployment history, and an operations surface, all self-hosted.

It is explicitly not a general-purpose PaaS pitch. The scope is small software on infrastructure your team already controls, and the project is CLI-first and repository-first, meaning the unit of work is a repository with a descriptor file rather than a dashboard you click through.

## How Compartment works: descriptor, control plane, worker, edge

The repository layout tells most of the architecture story. packages/cli is the user-facing compartment command. packages/sdk is the client surface the CLI and other clients use. packages/contracts holds shared public contracts, schemas, paths and generated reference inputs. packages/api is the control-plane API plus auth, persistence, migrations, and server-owned web serving. packages/worker handles deployment execution and background work. packages/edge is the ingress and access enforcement boundary. packages/console is a Vite and React browser control plane.

That is a conventional split, and the interesting part is where the work happens. A deploy is not executed by the CLI against the cluster directly. The CLI talks to the control-plane API, and the worker performs deployment execution. The edge sits in front of running apps and enforces access. Builds go through BuildKit, with railpack or Docker producing the image; the README states that if an app can build into a container image with Docker or Railpack, it usually fits the model.

Scheduling is configurable rather than fixed. The example environment file carries separate scheduling objects for builds and for data, with a runtimeClassName of gvisor in both, and the data scheduling object pins a node pool with the label compartment.dev/node-pool set to data. Concurrency is capped twice over: a global COMPARTMENT_MAX_CONCURRENT_BUILDS and a much lower per-organization COMPARTMENT_MAX_CONCURRENT_BUILDS_PER_ORGANIZATION. Those two numbers together are the clearest signal of intended scale.

## Installing Compartment and deploying a first app

The README quickstart installs a verified CLI through a shell script and then runs the installer. When no usable Kubernetes context exists, the CLI selects the managed-VM target, checks the host, shows one mutation review, and requests sudo only after confirmation. Nothing is changed before that confirmation step.

```bash
curl -fsSL https://compartment.dev/install.sh | sh
compartment install
```

If you already have a cluster you want to use, the README gives an explicit target flag instead of letting the CLI decide.

```bash
compartment install --target kubernetes
```

Next, prepare the application repository. The init command generates the descriptor, and the README calls this the smallest one that works: a name and a single service pointing at the repository root.

```yaml
name: internal-tools

services:
  web: .
```

Deploy and inspect. The README shows status and logs as the two follow-up commands, and both are the ones you would expect an operator to reach for first.

```bash
compartment deploy
compartment status
compartment logs
```

For branch-driven deploys, the README points at connecting the repository through the Console or with compartment source connect git, and refers to the Deploy using Git page in the public docs for the full flow. The README does not document rollback, so treat deployment history as something to inspect rather than something to reverse with a documented command.

## Running Compartment locally is a real dependency exercise

The development path is heavier than the install path, and the README is honest about it. Local development expects PostgreSQL through COMPARTMENT_DATABASE_URL, plus caddy, buildctl, docker and railpack on PATH. BUILDKIT_ADDR must point at a reachable BuildKit daemon. The Docker-compatible CLI and daemon run the loopback artifact registry; the README states plainly that they are not an application runtime target.

```bash
nvm use
pnpm install
cp .env.example .env
```

The README then shows the macOS-flavoured way to get the build tools in place, followed by the dev entry point.

```bash
brew install caddy buildkit
curl -sSL https://railpack.com/install.sh | sh
pnpm dev
```

The Node version is pinned in .nvmrc and package.json requires Node 24.15.0 with pnpm 10.6.3, so a mismatched local toolchain is a predictable first failure. The repository also asks contributors to read docs/specs/local-development.md before changing local runtime behavior, which is a reasonable sign that the local runtime has rules that are not obvious from the scripts alone.

## Where Compartment is the wrong tool

The per-organization build cap in the example environment file is set to 2. That is not a typo in the sample; it is a design assumption about how many deploys a single team runs at once. A team that expects to fan out dozens of parallel builds per organization will spend its time tuning that number and the BuildKit resources that go with it, and the defaults will not carry them.

The second limitation is operational. Compartment does not remove Kubernetes, it wraps it. The data scheduling example pins workloads to a labelled node pool and sets gvisor as the runtime class. If your cluster has no such node pool, no gVisor runtime class, or no BuildKit daemon, the managed install is the only path that avoids that work, and the README's alternative is to select an existing cluster explicitly and meet its expectations yourself.

The third is maturity. The most recent release in the repository is v0.12.0, published on 2026-08-18, and the version numbers before it move in small increments. Pre-1.0 software changes its contracts. The README does not document rollback, and it does not describe an upgrade procedure for the control plane. If a deployment goes wrong, the documented surface is status and logs, not a revert.

Finally, the project is wrong for anyone who wants a hosted product. The entire value proposition is that runtime control stays on infrastructure the team owns.

## Compartment compared with writing your own manifests

The obvious alternative is not another deployment product. It is a directory of Kubernetes manifests and a CI job that applies them. That approach has real advantages: no control plane to run, no additional API, worker, edge or console process, and no descriptor format to learn. Everything you need to know is in the Kubernetes API.

What you give up is everything Compartment adds around the workload. A manifest repository does not give you deployment history as a product surface, an access model with SSO, RBAC, roles and audit logs, or an edge that enforces access in front of the app. It also does not give you a single command that answers what is running and what it logged.

The difference in approach is where the state lives. With manifests, the cluster is the source of truth and your CI system is the driver. With Compartment, the control plane owns deployment state and the worker drives execution, which is what makes the history and access surfaces possible. That is also the cost: you now operate the control plane, and its database, alongside the cluster.

## Maintenance, releases, and the Apache-2.0 licence

The repository is not archived, and the last push was on 2026-08-18. Development is visible in the release cadence: v0.10.8 on 2026-08-07, v0.11.0 on 2026-08-17, and v0.12.0 on 2026-08-18. Two releases in two days suggests either a fast fix cycle or a versioning scheme that tolerates small increments; the repository does not explain which.

Upgrade cost is the part to check before committing. Because the control plane owns persistence and migrations, upgrading Compartment is not only a CLI swap. The API package holds migrations, and the README does not describe a supported upgrade path between minor versions. The release tooling in the repository (release-please-config.json, .release-please-manifest.json, and the release scripts) governs how versions are cut, not how an operator moves an existing installation forward. That gap is worth resolving with the project before you run it in front of a team.

Compartment is licensed under Apache-2.0, and the README links the LICENSE file at the repository root. Apache-2.0 is a permissive licence with an explicit patent grant, which matters for a self-hosted control plane that a company embeds in its own infrastructure. It is not a copyleft licence, so modifications you make do not have to be published. That is a general property of the licence text, not advice about your situation; if the control plane becomes part of a product you ship, have someone qualified read the terms.

## Conclusion

Adopt Compartment if your team already runs Kubernetes, wants deployment URLs and an access model for small internal apps without buying a managed platform, and can accept a pre-1.0 tool at 0.12.0. Do not adopt it if you have no cluster and no appetite for operating one, or if you need a documented rollback path today. Before installing, read docs/specs/local-development.md, check that your cluster satisfies the scheduling constraints in .env.example, and confirm the upgrade behaviour of the control plane across minor versions.

## FAQ

### What is Compartment and what does it do?

Compartment is a self-hosted Kubernetes deployment system for internal tools, private apps, and public services. It installs into an existing cluster or provisions a managed single-node Kubernetes host, then provides the runtime, URLs, access model, deployment history, and operations surface around applications in normal repositories.

### How do I install Compartment?

The README quickstart installs the verified CLI with a shell script from compartment.dev and then runs compartment install. When no usable Kubernetes context exists, the CLI selects the managed-VM target, checks the host, shows one mutation review, and requests sudo only after confirmation. To use an existing cluster instead, run compartment install --target kubernetes.

### What does a Compartment descriptor file look like?

The README calls this the smallest descriptor: a name field and a services map with a web entry pointing at the repository root. Running compartment init prepares it in an application repository.

### What do I need to run Compartment locally?

Local development expects PostgreSQL through COMPARTMENT_DATABASE_URL, plus caddy, buildctl, docker, and railpack on PATH, with BUILDKIT_ADDR pointing at a reachable BuildKit daemon. The README also pins the Node version in .nvmrc and requires pnpm 10.6.3.

### Is Compartment free to use?

Compartment is licensed under the Apache License 2.0, and the README links the LICENSE file at the repository root. The README does not describe any paid tier or hosted offering.

## Sources

- [Official documentation](https://compartment.dev)
- [Official README](https://github.com/compartmentdev/compartment#readme)
- [Project repository](https://github.com/compartmentdev/compartment)
- [Release notes](https://github.com/compartmentdev/compartment/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/compartmentdev-compartment
