GitOps by default
Every state change is a commit or pull request. `git log` is your deploy history — no imperative drift, no clicking around a UI to change prod.
Self-hosted · GitOps · Plain Docker
MajNet ships apps to your own hardware the way a platform should feel — every deploy is a commit, every environment is declarative, and there’s no Kubernetes to babysit.
Open source · One binary bootstraps a node · No control-plane SaaS.
A small, legible control plane you can actually read — two Rust services, plain Docker, and git as the source of truth.
Every state change is a commit or pull request. `git log` is your deploy history — no imperative drift, no clicking around a UI to change prod.
Static placement by trust zone — each workload has exactly one home node. No Swarm, no Kubernetes, no quorum. One reconciler drives each node directly.
Repos, teams, members, webhooks, and app scaffolding are fully bot-managed and declarative. Declare an app; the platform materializes the rest.
production (public, review-gated), stable / testing (VPN, auto-deploy), and ephemeral per-PR previews with a TTL. Placement follows the class.
SOPS + age secrets that rendering never decrypts, plus managed Postgres, MariaDB, Valkey and MongoDB with per-project logical DBs and backups.
The GitHub/Tailscale liaison and the node/secrets orchestrator hold strictly separate credentials — neither can act in the other’s domain.
Manage projects from a dashboard on your VPN — but every deploy is still a reviewed pull request.
The whole deploy loop is a pull request. Your review is the gate to production.
Add an app to your project’s ops repo — a name, a template, an image. Commit it. That commit is the intent.
The bot renders your manifests into per-environment branches and opens a pull request. Production waits for your review.
Merge the PR. The reconciler converges the node’s Docker state — blue-green, health-checked, digest-pinned.
A GitHub bot and a reconciler — with strictly separate credentials — drive plain Docker across trust-zoned nodes over a WireGuard mesh.
One source of truth
A root platform org holds global config; each project’s opsrepo holds its apps and SOPS-encrypted secrets. There’s no hidden state to drift from — reconstruct any node from git and a restore.
name: web
image: ghcr.io/acme/web@sha256:9f3c…
ingress:
host: app.example.com
port: 8080
database:
engine: postgresThe reach of a PaaS and the control of your own box — without a cluster to operate.
| MajNet | Kubernetes | Managed PaaS | Docker Compose | |
|---|---|---|---|---|
| Runs on your own hardware | Any Debian box | Self-managed | Their cloud | Any box |
| Git is the source of truth | Every deploy is a PR | Bring your own GitOps | Dashboard / CLI | Files, no workflow |
| Operational complexity | Two small services | High | Hidden from you | Low |
| Per-PR preview environments | Ephemeral, TTL | DIY tooling | Some tiers | None |
| Secrets never in env / plaintext | age + tmpfs | Base64 by default | Provider-held | .env files |
| Managed databases + backups | PG/MariaDB/Valkey/Mongo | Operators | Add-ons ($$) | Manual |
| Monthly cost | Your VPS bill | Cluster overhead | Scales with usage | Your VPS bill |
Bootstrap a node, install the GitHub App, add one line to the registry. Everything after is automated.