The private PaaS
you self-host.
Any server, any cloud, connected over WireGuard. Only the gateway faces the internet.
sudo bash -c "$(curl -fsSL meshploy.com/install.sh)" One public node.
Everything else is dark.
api.acme.com. DNS resolves to the gateway, the only machine in the cluster with a public IP.:443. Wildcard cert issued via DNS-01 challenge against CoreDNS. No cert-manager, no Ingress CRDs.Host header, queries Postgres for the matching route, resolves the target mesh IP and port. Cache refreshes every 30s.api.acme.com. DNS resolves to the gateway — the only machine in the cluster with a public IP.:443. Wildcard cert issued via DNS-01 challenge against CoreDNS. No cert-manager, no Ingress CRDs.Host header, queries Postgres for the matching route, resolves the target mesh IP and port. Cache refreshes every 30s.100.64.0.x:3000 receives the proxied request and responds back through the same encrypted path to the gateway.Five deliberate departures
from the way things are done.
Each of these choices replaces a common dependency with something smaller, more direct, and debuggable by one person at 2am.
Meshploy is a routing layer first. Deployments are built on top of it, not the other way around.
A routes table, not an Ingress controller.
Routes live in Postgres. The proxy caches in memory and refreshes every 30s. Adding a route is a single API call, no deploy step needed.
AES-encrypted columns, not k8s Secrets.
Secrets are stored as encrypted columns in the database. Application code never handles encryption directly. No external key management service needed.
K8s Jobs, not external CI.
Build pipelines run as ephemeral K8s Jobs on nodes labelled role=builder. Logs stream back over the same API. No GitHub Actions runners to maintain.
Caddy handles TLS. Your DNS stays yours.
Caddy renews certificates automatically. A built-in DNS server handles the domain verification challenge. No extra operators or config files to manage.
WireGuard mesh, not VPC lock-in.
Every node (Hetzner, AWS, your home laptop) joins the Headscale-managed mesh. Stable IPs in 100.64.0.0/10. Cross-cloud by default.
Authorization is explicit, not hidden.
Every protected endpoint calls requireUser() directly. Access control is visible at the point where it matters, not tucked away in a router group you have to go looking for.
// explicit auth at every protected call site func (h *Handler) GetNode(ctx, input) (...) { if _, err := requireUser(ctx); err != nil { return nil, err } return h.svc.GetNode(ctx, input.ID) }
Three commands.
One control plane.
Point a subdomain at your server, run one script, and you have a working PaaS in about five minutes. Workers join by pasting one command.
Point your domain
Add an NS record at your registrar pointing a subdomain at your server's IP. Meshploy runs its own DNS server so no third-party plugin is needed. DNS takes a few minutes to propagate.
# at your registrar meshploy.acme.com NS 65.108.42.18
Install the gateway
Run as root on any internet-facing Linux server. Installs Docker if needed, brings up Caddy, Headscale, CoreDNS, and the API. The script verifies DNS before completing.
# on the public node sudo bash -c "$(curl -fsSL \ meshploy.com/install.sh)"
Join workers
Same script, worker flag. The node self-registers with a provisioning token, joins Headscale, and is ready to schedule workloads.
# on each worker sudo meshploy node install \ --token mprov-8a3f...b712
Three positions
against the alternatives.
Meshploy isn't trying to be everything. It's trying to be the right shape for the gap between "deploy to one server manually" and "hire a platform team."
vs. Vercel · Railway · Render
vs. Coolify · Dokploy · Uncloud
vs. raw Kubernetes
Everything is one binary,
at /usr/local/bin/meshploy.
A static Go binary installed by the setup script. It wraps the REST API and shells out to install.sh / uninstall.sh for node-level operations. Authenticate once, then manage everything from anywhere.
Boring tools,
composed deliberately.
None of these were built for Meshploy. The question was: which mature, well-understood tools assemble into a coherent stack one person can operate and understand completely.
Self-host in 5 minutes.
Scale across clouds in 5 hours.
One curl on a fresh box. One NS record at your registrar. That's it for the gateway. Workers join by pasting one command.