podman-compose: running docker-compose.yml without a Docker daemon
a script to run docker-compose.yml using podman
At a glance
- What is it?
- podman-compose is a single-file Python implementation of the Compose Spec that shells out to podman instead of talking to a daemon. It fits rootless, single-machine workflows; it is not a Kubernetes replacement and its own metadata labels it alpha.
- Who is it for?
- Adopt podman-compose if you want to keep an existing Compose file and run it rootless on one machine, without a long-running daemon. Do not adopt it if you need multi-node scheduling (the README points to k3s, MiniKube or OKD for that) or if you depend on Compose features the project has not implemented.
- Can I use it commercially?
- Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What podman-compose is for, and who it is not for
The project describes itself as an implementation of the Compose Spec with a Podman backend. The goal is narrower than "Docker Compose, but with Podman": the README lists two focuses, rootless operation and a daemon-less process model in which the script directly executes podman. There is no service running in the background holding state between invocations. Each command parses your YAML and issues podman calls.
That makes it a fit for developers and small deployments that already have a docker-compose.yml and want it to run on a machine where Docker is absent or unwanted, particularly under an unprivileged account. It is a poor fit for anyone who needs orchestration across hosts. The README is explicit about that boundary: for a production-like single-machine containerized environment it points at k3s and MiniKube, and for multi-node clusters at an OpenShift or Kubernetes distribution such as OKD. Treat podman-compose as a local development and single-host convenience layer, not as a scheduler.
One thing to weigh before you start: the project's own pyproject.toml carries the classifier "Development Status :: 3 - Alpha". The README does not repeat that label, and the project has published 1.x releases, but the packaging metadata is the honest signal about how the maintainers rate its maturity.
The mechanism: a Python script that executes podman
There is no protocol layer here. The README states the project depends on podman, optionally the podman dnsname plugin, Python 3.9 or newer, PyYAML and python-dotenv, and that it is "formed as a single Python file script that you can drop into your PATH and run." The repository confirms the shape: the top level contains podman_compose.py alongside pyproject.toml, requirements.txt and a tests directory, and the entry point is declared as podman-compose = "podman_compose:main".
So the data flow is: read the Compose file with PyYAML, apply environment variables from a .env file through python-dotenv, then translate the result into podman invocations. The README's own comparison makes the consequence clear. If you instead point unmodified docker-compose at a podman.socket, you lose the process model, and it gives the example that docker-compose build will send a possibly large context tarball to the daemon. Running the script directly avoids that daemon round trip.
The dependency list also tells you where the sharp edges are. Container-to-container name resolution on the same network depends on the dnsname plugin, which the README says is usually packaged as podman-plugins or podman-dnsname and is not pulled in by default. It adds the qualification that this is not necessary when podman uses netavark as its network backend. That single sentence is the difference between a working compose file and one where service names do not resolve, and it depends on your Podman version rather than on anything you configure in the YAML.
Installing podman-compose and running podman compose up
The README lists several installation routes. The PyPI route is the shortest, and adding --user keeps it inside a regular user's home without root, which matches the project's rootless emphasis.
pip3 install podman-composeDistribution packages exist for Debian, Fedora (from f31) and Homebrew. On Ubuntu or Debian the README gives this command, which is the answer to the common "podman compose install on Ubuntu" question:
sudo apt install podman-composeOn Fedora the equivalent is sudo dnf install podman-compose. If you prefer no package manager at all, the manual route drops the script straight into your PATH:
curl -o ~/.local/bin/podman-compose https://raw.githubusercontent.com/containers/podman-compose/main/podman_compose.py
chmod +x ~/.local/bin/podman-composeAfter that, a first real use is the same file you would hand to docker-compose. The repository ships working examples under examples/, including hello-app, hello-app-redis, busybox, wordpress and nvidia-smi, so you can try the tool without writing a compose file first. From a directory containing a docker-compose.yml, the commands are the familiar ones:
podman-compose up -d
podman-compose ps
podman-compose downThe README does not document a rollback command or a way to revert a partially applied up, so treat a failed up as something you clean up with down rather than something the tool undoes for you. If the shell reports podman-compose: command not found, the cause is almost always that the install location is not on PATH; the manual route above writes to ~/.local/bin, which is not on PATH by default on every distribution.
The 0.1.x to 1.x break, and what it says about upgrade cost
The README documents one real migration hazard. If you are upgrading from podman-compose 0.1.x, the global option -t for setting a mapping type such as hostnet no longer exists. The replacement is to express the same intent in the Compose file, for example network_mode: host in the YAML. Any script or CI job that passes -t will fail after the upgrade, and the fix is to edit the compose file rather than the command line.
The version guidance is tied to Podman itself. The README says that on podman before 3.1.0 you may need to stay on the legacy 0.1.x branch, because that branch used mappings and workarounds to compensate for rootless limitations, and that modern podman (>=3.4) does not have those limitations, so the 1.x branch is appropriate. Note the gap between 3.1.0 and 3.4 in the README's own wording; if your Podman sits in that range, the documentation does not tell you which branch to pick.
Upgrade cost otherwise looks low. The runtime dependency set is three packages (podman, PyYAML, python-dotenv) plus Python 3.9 or newer, and the project is a single module. There is no database, no state directory to migrate and no daemon to restart. The main recurring cost is behavioural: because the tool translates Compose semantics onto podman rather than implementing them natively, a compose file that exercises less common keys may behave differently than it does under docker-compose.
Where podman-compose is the wrong tool
The clearest limitation is scope. This is a single-machine tool. Nothing in the README claims scheduling, failover, or multi-node placement, and it redirects that audience to k3s, MiniKube or a Kubernetes distribution. If your compose file is really a stand-in for a deployment topology, you are using the wrong layer.
The second limitation is dependency resolution inside the network. The README states that containers resolving each other by name on the same CNI network requires the dnsname plugin, which is not installed by default, and that this requirement disappears when podman uses netavark. This is a host configuration concern that a compose file cannot express. A team that standardises on a compose file and expects identical behaviour on every developer machine will hit this if their machines differ in network backend or in whether the plugin package is present.
The third is the alpha classifier in pyproject.toml. That is the project describing itself, not an outside assessment. Combined with a translation layer that must track an external specification, it means you should expect gaps in less-travelled Compose keys and should test the specific keys you rely on rather than assuming parity with docker-compose. The repository does carry unit and integration test suites, which the README shows how to run, but the README does not publish a compatibility matrix mapping Compose Spec features to implementation status.
podman-compose versus docker-compose on a podman socket
The README names the alternative itself: enable podman.socket and use unmodified docker-compose against it, an approach it links to a Fedora Magazine article. The difference is architectural, not cosmetic. With the socket, docker-compose keeps its normal client-daemon model and podman presents a Docker-compatible API. With podman-compose, the script executes podman directly and there is no daemon in the path.
The README gives one concrete consequence of the socket approach: docker-compose build will send a possibly large context tarball to the daemon. That matters on slow disks or large build contexts, and it is the kind of cost that shows up as latency rather than as an error. The socket route buys you the real docker-compose implementation, which is more likely to match documented Compose behaviour exactly, at the price of running a background service and accepting the daemon round trip.
A related distinction that trips people up is naming. The phrase "podman compose" appears both for this project and for the podman subcommand that delegates to an external compose provider. They are not the same thing, and the README does not describe the subcommand. If a tutorial tells you to run podman compose and another tells you to run podman-compose, check which binary is actually installed before you debug anything else.
Licence and what GPL-2.0-only means for distribution
The project is GPL-2.0-only, stated in pyproject.toml as license = "GPL-2.0-only", and the repository carries a LICENSE file. This is a copyleft licence, which is a different situation from the permissive licences common in developer tooling.
The practical question is how you distribute it. If you install it from PyPI, apt, dnf or Homebrew, you are a user and the distributor's obligations are theirs. If you bundle the script into a product image, vendor it into an internal artifact, or ship a modified podman_compose.py, the copyleft terms attach to that distribution. The README's manual install route, which curls podman_compose.py directly into your PATH, is the case where you should look at the licence text yourself rather than assume. None of this is legal advice; the LICENSE file in the repository is the authority, and if you are embedding the tool in something you ship, that is a conversation for whoever handles licensing on your side.
Editorial conclusion
Adopt podman-compose if you want to keep an existing Compose file and run it rootless on one machine, without a long-running daemon. Do not adopt it if you need multi-node scheduling (the README points to k3s, MiniKube or OKD for that) or if you depend on Compose features the project has not implemented. Before committing, verify two things on your own host: whether your Podman uses netavark or CNI, since the dnsname plugin is only needed for CNI, and whether the specific subcommands your workflow uses behave as your docker-compose workflow did.
Frequently asked questions
How do I install podman-compose?
The README lists pip3 install podman-compose for the latest stable release, with --user to install into a regular user's home without root. It is also packaged for Debian (sudo apt install podman-compose), Fedora from f31 (sudo dnf install podman-compose) and Homebrew (brew install podman-compose).
How do I install podman compose on Ubuntu?
The README gives sudo apt install podman-compose for Debian, which covers Ubuntu. Alternatively pip3 install podman-compose works there too, and the manual route curls podman_compose.py into ~/.local/bin and marks it executable.
How do I run podman compose up?
From a directory containing a docker-compose.yml, run podman-compose up -d, then podman-compose ps to check status and podman-compose down to stop. The repository ships ready-made files under examples/, including hello-app and hello-app-redis, if you want to try it before writing your own.
What is the difference between podman compose and podman-compose?
The README describes this project, podman-compose, as a single Python file that directly executes podman with no running daemon. The similar-looking podman compose subcommand is not documented in the README, so the two should not be treated as interchangeable; check which binary is installed on your machine.
Can I install podman-compose on Windows?
The README lists pip, Debian, Fedora, Homebrew and a manual curl route, and does not document a Windows installation. The pyproject.toml classifiers say Operating System :: OS Independent for the Python package, but the README gives no Windows-specific instructions.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/containers-podman-compose)