The self-hosted PaaS drawer is not empty. Coolify, Dokploy, CapRover, Dokku, Kamal. If you have wanted a Heroku you actually own, someone has already built you three of them.
So when Openship showed up in July 2026 and hit several thousand GitHub stars in about a week, the reasonable reaction was skepticism. Another dashboard for docker compose up.
Having read through it, there is one architectural decision here that is actually different, and it is the kind of difference you feel on a 4 GB VPS. This post covers what that decision is, how to get the thing running three different ways, and an honest read on whether you should put anything you care about on it yet.
The one idea that matters
Every self-hosted PaaS in that drawer runs its entire control plane on your server. The dashboard, the database backing it, the build system, the CI runner, the webhook listener, and your actual apps all share one box and one set of resources.
You notice this the first time a Next.js build on a 4 GB VPS starves the running production container and takes your site down. Your deployment tool became a reliability risk for the thing it deploys.
Openship inverts it. The control plane runs on your machine, or on a separate box, and drives your servers over SSH. Builds happen locally. What gets shipped to production is a finished container image.
You Your server
┌──────────────────────┐ ┌──────────────────────┐
│ Desktop / Web UI │ SSH │ │
│ Build pipeline │────────→│ Your apps. Only. │
│ CLI / API │ │ │
└──────────────────────┘ └──────────────────────┘
Enter fullscreen mode Exit fullscreen mode
The practical consequences are worth spelling out:
Your production server does not need build-sized resources. It runs containers. That is it. A small VPS goes further.
Your deployment tool has no public attack surface. In the desktop configuration, Openship exposes no port and has no public URL. The only thing reachable from the internet is an app you deliberately gave a domain to.
Builds use your laptop's CPU, which is almost certainly faster than your VPS's shared vCPUs.
The tradeoff is honest and the maintainers state it: the dashboard is only up while your machine is. No teammate access, no phone access, and push-to-deploy webhooks need a stable public endpoint that a laptop is not. If you need any of those, you run the control plane on a server instead, at which point you have re-created the normal arrangement, just deliberately rather than by default.
Building on the server is also available as a config flag. The README's phrasing is that it is a config flag, not a religion.
What is actually in the box
Openship bundles more than deployment:
| Area | What you get |
|---|---|
| CI/CD | Push-to-deploy, preview environments, staging and prod flows, rollbacks |
| Stacks | Node, Python, Go, Rust, PHP, Ruby, Java, .NET, Docker, monorepos |
| Data | Postgres, MySQL, MongoDB, Redis, workers, WebSockets, storage |
| Domains and SSL | Let's Encrypt automation via OpenResty and certbot, wildcards, auto-renewal |
| CDN | Edge caching, HTTP/3, Brotli, instant purge |
| Built-in SMTP with DKIM, SPF, DMARC | |
| Backups | Scheduled database and volume backups, one-click restore, exportable |
| Automation | REST API, and MCP so AI agents can drive it |
The built-in mail server is the unusual one. Running your own SMTP with correct DKIM, SPF, and DMARC is genuinely annoying, and most self-hosted PaaS tools tell you to go use SES or Mailgun. Whether it survives contact with real deliverability is a separate question, but it is a real differentiator on the feature list.
Under the hood it is a TypeScript monorepo: an Electron desktop app, a Next.js dashboard (React 19, Tailwind 4, xterm.js for terminals), and a CLI built on Commander and Clack. A single OPENSHIP_TARGET environment flag decides whether an instance behaves as desktop, selfhosted, or cloud, which is why the same codebase powers the local app and the managed SaaS.
Pick your setup first
The install path depends entirely on who is using it and whether it needs to be up when your machine is off.
| Setup | Use when | Where the control plane runs |
|---|---|---|
| Desktop app | Just you, private | Your machine, driving servers over SSH |
| Self-hosted on a server | Team, always-on, CI, push-to-deploy | A Linux box at a public URL, invite-only |
| Openship Cloud | You want zero ops | Managed |
Decide before you install. Switching later is possible but it is not a no-op.
Path 1: Desktop app (solo, and the recommended one)
Download the build for your OS from openship.io, or let the CLI fetch it:
openship install
Enter fullscreen mode Exit fullscreen mode
On Linux the download is an AppImage:
chmod +x Openship.AppImage && ./Openship.AppImage
Enter fullscreen mode Exit fullscreen mode
On first launch it asks what you want to manage:
- This Machine — manage the local box.
- Another Server — add a remote server over SSH with host, user, and key. There is a Test Connection button. Use it before you go further, because SSH problems surface much more clearly here than mid-deploy.
This is the configuration where Openship's architecture pays off most. Nothing about the platform is exposed. It is worth starting here even if you eventually want the server setup, because you learn the model without also debugging a public deployment.
Path 2: CLI on a server (teams and CI)
Point your domain's DNS A record at the server first. Doing this after the fact means waiting on propagation while the certificate step fails repeatedly.
Install the CLI, which bundles the API and dashboard:
npm i -g openship
# or
curl -fsSL https://get.openship.io | sh
Enter fullscreen mode Exit fullscreen mode
Then bring it up:
openship up --public-url https://ops.example.com --managed-edge
Enter fullscreen mode Exit fullscreen mode
What each part does:
-
openship upinstalls Openship as a background service that starts on boot and auto-restarts, then runs a setup wizard that creates the first admin and attaches your domain. -
--public-urlmakes the dashboard reachable at your domain. Login is required and public signup is disabled; everyone else joins by invite. -
--managed-edgeinstalls OpenResty and provisions a free Let's Encrypt certificate, routing your domain to the dashboard. Omit this if you already run your own reverse proxy, or you will have two things fighting over ports 80 and 443.
For an attached, non-service run:
openship up --foreground
Enter fullscreen mode Exit fullscreen mode
A nice touch: once it is up, Openship registers itself as an app in its own dashboard. You manage its domain, tail its logs, and see it listed as Live alongside everything else. Self-hosting the control plane as a first-class app rather than a special case is the sort of detail that suggests someone actually ran this in anger.
If you lose the admin password:
openship reset-admin-password
Enter fullscreen mode Exit fullscreen mode
That works locally on the box without signing in, using the internal token. Which also means: anyone with shell access to that server owns your Openship instance. Treat SSH access accordingly.
Path 3: Docker Compose (and why the maintainers steer you away)
git clone https://github.com/oblien/openship.git && cd openship
cp .env.example .env
docker compose up -d
Enter fullscreen mode Exit fullscreen mode
This works, but the docs explicitly label it as not the recommended path, and the reason is worth understanding rather than ignoring.
The compose stack gives the control-plane container access to the host Docker daemon. That is effectively host-level privilege. A container that can talk to the host's Docker socket can start a privileged container, mount the host filesystem, and escape. It is a well-understood escalation path, not a theoretical one.
There are legitimate reasons to want a containerized control plane. Just know that you are trading the security posture that was the point of the architecture in the first place.
Deploying something
Once the control plane is running, the app workflow is short:
cd my-project
openship init # links this directory to a project (.openship/project.json)
openship deploy # triggers a deployment
openship logs <deploymentId> -f # stream build and runtime logs
Enter fullscreen mode Exit fullscreen mode
Openship detects the stack, builds it, wires up config, and ships the container. No YAML pipeline, no Dockerfile required unless you want one. Existing Docker Compose files can be deployed as-is.
The auto-detection claim is the one I would test against your actual repo before believing it. Framework detection is easy for a vanilla Next.js app and gets progressively less magical as your monorepo gets weirder.
CLI cheat sheet
Instance management:
| Command | Does |
|---|---|
openship up [--foreground] |
Start as a service, or attached |
openship stop |
Stop the service |
openship status [--json] |
Running state, ports, API health |
openship open |
Open the dashboard in a browser |
openship update |
Update CLI and bundled server |
openship doctor |
Diagnose config, context, runtime |
Deploy and inspect:
| Command | Does |
|---|---|
openship init |
Link current directory to a project |
openship deploy |
Trigger a deployment |
openship logs <id> [-f] [--tail N] |
View or stream deployment logs |
openship deployment |
List and manage deployments |
openship project |
List and manage projects |
openship service |
Services within a stack |
openship domain |
A project's domains |
Infrastructure and auth:
| Command | Does |
|---|---|
openship server |
Manage self-hosted SSH servers |
openship system |
Read and update instance settings |
openship mail |
Mail server setup |
openship backup |
Backup policies and schedules |
openship login / logout
|
Authenticate with a Personal Access Token |
openship context |
Switch which instance the CLI talks to |
openship api <method> <path> |
Authenticated request to any API route |
--json works on most read commands, which makes this scriptable in CI. And openship api following the gh api pattern is a good call, since it means you are never blocked waiting for a CLI command to be written for an endpoint that already exists.
The MCP angle, with a caveat
Openship ships MCP support so AI agents can drive deployments. The pitch is roughly: add the MCP server, and your agent can do the work.
Worth pausing on. You are handing an agent deploy permissions, secrets access, and production rollback control. Standard MCP hygiene applies and applies harder here: scope the tools you expose, point agents at staging rather than production, use a Personal Access Token with the narrowest permissions that work, and keep an audit trail of what the agent did.
An agent that can deploy can also deploy the wrong thing at 3am while nobody is watching.
How ready is this, actually
Being straight with you, since dev.to posts that skip this part are advertising.
Known rough edges. As of July 2026 there are open reports of breakage in the CLI installer and in the self-hosted SSH deploy path, including deploys failing immediately after a successful Docker build. The issue queue is active, which is a good sign for responsiveness and a clear sign it is still early.
License. This one matters and is easy to get wrong. Openship launched under AGPL-3.0 plus the Commons Clause, which is source-available rather than open source and prohibited offering it as a hosted service.
Roadmap gaps. Multi-node clusters, load balancing UI, private networking, and visual CI/CD pipelines are all listed as coming, not shipped. If clustering is a requirement, this is not your tool yet.
Should you use it
Try it now if you are a solo developer or small team, you have side projects or non-critical services, and the local-build architecture appeals to you. The desktop app is genuinely low-risk to experiment with, since it does not expose anything and does not need a server to evaluate.
The architecture is the real contribution here. Keeping build infrastructure off the production box is correct, and it is a bit odd that it took this long for a self-hosted PaaS to treat it as the default rather than an option. Even if Openship itself does not win the category, that idea should propagate.
Links:
If you run it on a real VPS, especially the SSH deploy path, post what broke in the comments. Early projects get better fastest when the failure reports are specific.
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.