What is ply
ply is npm for containers. Your app is a package, its OS-level dependencies are packages, an image is a resolved lockfile, and the runtime is a boring static binary that mounts the closure and execs your entrypoint.
curl -fsSL https://plybox.sh/install.sh | shThere is no daemon, no registry server, no Dockerfile, and no build cache.
An image is a single deterministic file you can scp around. Any file host —
GitHub Releases, an S3/R2 bucket, a plain directory — is a fully working
package registry.
#The mental model
ply borrows one proven mechanism from each of four tools:
| Borrowed from | What ply takes |
|---|---|
| Cargo | TOML manifest (ply.toml), flat dependency list, lockfile (ply.lock), no install scripts ever |
| Go modules | Minimal Version Selection — deterministic resolution, no solver, upgrades only when you change the manifest |
| Nix | A package is its content hash; names are claims, hashes are proof |
| Homebrew | Each package owns its own prefix (/opt/<name>-<version>/) — conflicts impossible by construction |
At run time these compose: squashfs images loop-mount read-only, overlay
stacks them in dependency order, namespaces + seccomp + cgroups isolate the
process, and your app runs as an ordinary child process. Ctrl-C stops it.
ply ps reads state files. Nothing is resident.
#Where it shines
- 1–5 VPSs, small teams — deploys are
scp+ one command; the whole platform is a 5 MiB binary - CI sandboxes — hermetic, content-addressed, offline-capable
- Edge / IoT — no daemon to babysit, factory reset =
rm -rf /var/lib/ply - AI-agent sandboxing — thousands of cheap, isolated, throwaway executions
#Where to go next
- Quickstart — running your first app in five minutes
- Dependencies & lockfiles — how resolution works
- Registries & publishing — shipping images anywhere
- ply vs Docker — an honest comparison