SMALL TOOL. UNIX SOUL.

Containers.
The Unix way.

Compose packages.
Ship files. Run processes.

A daemonless container runtime and package manager for Linux. Explicit dependencies, inspectable files, and a process you control.

curl -fsSL https://plybox.sh/install.sh | sh

Linux x86_64 / arm64 · Open source · Pre-1.0

A CONTAINER IS A COMPOSITION
ply.lockCOMPOSITION VIEW
INDEPENDENT PACKAGESYOUR APPhello.imgRUNTIMEpython3.imgBASEdebian.imgply.lockEXACT VERSIONS + HASHEScompose at run timeapp + runtime + baseply runNO DAEMONLINUX NAMESPACES / CGROUPS / FILES
Separate packages. One declared composition.

Pin the parts. Ship the app.

The lockfile pins exact versions and hashes. Your app image carries dependency references; shared packages stay separate.

❯ ply build .

ply.toml → ply.lock → hello-0.1.0-linux-x64.img

COMPOSE PACKAGES. SHIP FILES. RUN PROCESSES.THE PLY MODEL
LESS MACHINERY.
MORE LINUX.
One static binary No daemon No Dockerfile Just files & processes

FROM YOUR SHELL TO YOUR SERVER

Ship it with scp.
Yes, really.

Your app ships as a file with locked dependency references.
The packages come together when it runs.

ply.tomlTOML
# A whole container, in plain text.
[package]
name = "hello"
version = "0.1.0"
base = "debian@13"
entrypoint = ["python3", "app.py"]

[dependencies]
python3 = "3.13"

[sources]
default = "https://registry.plybox.sh/ply/{package}"
Your app.py lives beside this file. That’s the setup.
  1. 01

    Build your package.

    $ ply build .

    Resolve dependencies. Lock the hashes. Emit an image.

  2. 02

    Put it on your server.

    $ scp hello-*.img server:

    SSH, a file server, a USB drive. It’s just a file.

  3. 03

    Run it like a process.

    $ ssh server ply run hello-*.img

    Dependencies fetch by hash. Your app gets its own sandbox.

Foreground by default. Ctrl-C works. Exit codes propagate.Walk through the quickstart

GOOD TOOLS GET OUT OF YOUR WAY

Less magic.
More understanding.

For people who want to know what’s running,
where the bytes came from, and how to stop it.

Compose explicit parts.

Declare a set of named dependencies. The lockfile pins each version and hash; shared packages keep their own identity.

Meet the package model

Keep it in files.

Intent in TOML. Packages in a content-addressed store. Runtime state in JSON. Files you can inspect, copy, and version with familiar tools.

See how the pieces fit

Run without a daemon.

Linux provides namespaces and cgroups. Your app is a process, logs flow to stdout, and signals work. No central Ply daemon to keep alive.

Read the architecture
$ man ply-vs-dockerThe tradeoffs, honestly.

YOUR MACHINE. YOUR RULES.

Make yourself at ~/home.

Start with your app. Bring your favorite tools.

Let’s build something