I run a handful of small VPS boxes for side projects. For a while my "deploy setup" was the usual trio: a CI runner (Jenkins, then Drone), something to push releases to servers (Ansible / Kamal scripts), and Portainer to actually see what was running and poke at containers.
On a 2GB box, wiring and babysitting three separate tools was more overhead than the apps I was shipping. So a few weeks ago I started building the thing I actually wanted: CI/CD + multi-server deployment + basic ops, in a single Go binary with zero runtime dependencies.
It's called Pipewright. You scp one file to a server, run it, open the browser — that's the whole install.
What it actually does
-
Visual pipeline builder — a two-level (stage → job) DAG canvas. Horizontal links run serially, vertical ones run in true parallel. It round-trips with
.pipewright.yml, so you can click or commit your pipeline. - Isolated builds — version-pinned, container-isolated build steps with dependency caching; artifacts (images / JARs / dist bundles) you can push to a private registry.
- Agentless deploys over SSH — zero-downtime switchover + rollback on failure, fan-out to multiple servers with partial-failure visibility.
- Server & container ops — manage containers / images / stacks / volumes / networks across hosts, live stats, logs, and an in-browser terminal.
- It can update itself — checks GitHub for the latest release and does a download → checksum verify → atomic replace → restart, from the UI.
The stack
Go backend, Vue 3 frontend, everything embedded into the one binary. SQLite by default (zero setup), MySQL if you want it. Auth is argon2id + CSRF, credentials live in an encrypted vault (never echoed back in plaintext), and there's an append-only audit log. ~50MB binary, runs comfortably on a tiny box.
What I learned building it
-
Embedding the whole frontend into the Go binary (
embed.FS) is underrated. One artifact, no nginx, no separate static host. - Self-update is a great forcing function. The moment your tool updates itself in production, you stop being sloppy about release artifacts, checksums, and atomic file replacement. I've been dogfooding Pipewright to ship its own releases.
- "One binary for all of it" is a real design tension. It's tempting to keep adding surface area. I keep reminding myself the goal is the opposite of Jenkins-at-scale: the lightest thing that still does the full build → deploy → watch loop for a few servers.
What it's NOT
It's not trying to replace GitLab/Jenkins for a 200-engineer org. No multi-tenant RBAC, no massive plugin ecosystem. If you're running a big org, use the big tools. If you're a solo dev or small team who just wants build → deploy → ops without standing up three services, that's exactly who I built it for.
It's early (a few weeks old) and I'm actively building. I'd genuinely love feedback — especially on whether the "all-in-one binary" framing makes sense to you, or whether it's doing too much.
Repo (MIT, screenshots + one-command quickstart): https://github.com/huangchengsir/pipewright
Thanks for reading 🙏


Top comments (0)