# podup
docker-compose translator and runner for rootless Podman. Reads a
docker-compose file, translates it to the native libpod REST API, and manages
the container lifecycle (`up`/`down`/`logs`/`exec`/…). A single static Rust
binary — no daemon, no Python runtime.
[](https://github.com/Glyndor/podup/actions/workflows/ci.yml)
Package: [crates.io/crates/podup](https://crates.io/crates/podup) · MSRV 1.85 · License: Apache-2.0
<img src="docs/assets/podup-demo.gif" alt="podup running a compose stack on rootless Podman" width="760">
## Install
### Debian / Ubuntu (apt) — recommended
Register the signed Glyndor repository and install — copy-paste:
```bash
The installer verifies the keyring package's Ed25519 signature against its
pinned release key before anything is installed (fail-closed). The keyring
package registers `https://apt.glyndor.net` and ships the signing key, so podup
updates (and key renewals) arrive through `apt upgrade` — the apt build omits
self-update since apt owns upgrades. Requires **Podman ≥ 5.0** (rootless).
To register the repository by hand instead, fetch the keyring and check the
key's fingerprint against the one published in the
[apt repository README](https://github.com/Glyndor/apt#verify-the-signing-key):
```bash
curl -fsSLO https://apt.glyndor.net/glyndor-archive-keyring.deb
sudo dpkg -i glyndor-archive-keyring.deb
gpg --show-keys /usr/share/keyrings/glyndor.gpg # compare the fingerprint
sudo apt update && sudo apt install podup
```
<details>
<summary><b>Other methods — Linux/macOS script · Windows · build from source · self-update · Podman version · platforms</b></summary>
### apt, one-liner (script)
Same as above via the install script (registers the repo, then installs):
```bash
### Linux / macOS (install script)
```bash
### Windows (PowerShell)
```powershell
Both installers verify the Ed25519 signature over `SHA256SUMS` and fail closed
otherwise.
### Build from source
```bash
cargo build --release
```
### Self-update
```bash
podup update # download and install the latest signed release
podup update --check # report whether a newer release exists, install nothing
```
`podup update` replaces the running binary in place only after verifying the
release's Ed25519 signature and SHA-256 checksum — it fails closed otherwise. See
[docs/self-update.md](docs/self-update.md) for the trust model.
### Podman version
podup tracks the **latest stable Podman** and supports its **last two majors —
Podman 5.x and 6.x**. It talks to Podman's native libpod API (still versioned
5.x — 5.2.0 on Podman 6), so it needs **Podman ≥ 5.0**. Both supported majors
run the integration suite in CI on every engine change (Fedora 44 for the
latest 5.x, rawhide for 6.x). Many distributions still ship 4.x — check
`podman --version` and upgrade if needed. Fedora, Debian trixie/sid and recent
Ubuntu releases carry 5.x; on an older release, install or upgrade Podman
following the official guide: <https://podman.io/docs/installation>.
### Platforms
Linux, macOS and Windows (x86_64 and arm64). On macOS and Windows podup talks to
the `podman machine` VM through its host-side `unix://` socket or `npipe://`
named pipe; the socket must be local (remote `tcp://`/`ssh://` are rejected).
</details>
## Quick start
```bash
podup up -d # start the stack in the current directory
podup ps # see what's running
podup down -v # tear down and remove volumes
```
Full command reference: [docs/commands.md](docs/commands.md).
## Design
Rootless-native libpod API, real compose-spec support (`extends`, profiles,
`develop.watch`, inline secrets), and systemd Quadlet export. The Rust library
crate is consumed by [helmly-agent](https://github.com/Glyndor/helmly-agent);
API docs at [docs.rs/podup](https://docs.rs/podup).
```mermaid
sequenceDiagram
autonumber
participant Y as docker-compose.yml
participant P as podup
participant L as Podman · libpod REST
Y->>P: parse · substitute · resolve depends_on
P->>L: create networks · volumes · secrets
P->>L: start containers in order
L-->>P: health / status
P-->>Y: stack up
```
## Benchmarks
Peak memory and per-operation latency measured against docker-compose and
podman-compose, same Podman instance, same digest-pinned images, median of 10
runs.
<img src="docs/assets/bench.svg" alt="Bar chart: podup uses ~7 MiB vs 69 MiB for podman-compose, and is 7–15x faster per op" width="760">
Full tables and methodology: [docs/benchmarks.md](docs/benchmarks.md).
## Documentation
- [Commands](docs/commands.md)
- [Migrating from Compose](docs/docker-migration.md)
- [Benchmarks](docs/benchmarks.md)
- [Self-update](docs/self-update.md)
- [Security model](docs/security-model.md)
## License
[Apache-2.0](LICENSE) — report vulnerabilities privately via the **Security** tab, never in a public issue.