Releases: modern-python/compose2pod
Release list
0.1.1
compose2pod 0.1.1 — accept Compose extension fields
A patch release that stops rejecting valid compose documents which carry
Compose x- extension fields. The validator was over-strict: a top-level
x- block — the idiomatic place to hold a YAML anchor for reuse across
services — raised unsupported top-level keys. Such documents now convert.
Fix
- Compose
x-extension fields are accepted. Per the Compose spec, any
mapping key prefixedx-is user data that tools ignore.validate()now
skipsx--prefixed keys silently at every level it inspects — top level,
service, and healthcheck — instead of raising. The common pattern of holding
shared config in a top-levelx-*anchor block and merging it into services
(&anchor/<<:) works as-is: PyYAML resolves anchors and merge keys at
load time, and the leftover top-levelx-key no longer trips the validator.
Downstream
No action needed — additive and backward compatible. Documents that previously
failed with unsupported top-level keys: ['x-...'] now emit a pod script;
nothing that converted before changes.
Internals
- New
architecture/supported-subset.mdpins the authoritative accept / ignore
/ reject matrix (including thex-rule and the note that abuildsection
is accepted but never built — the--imagevalue is substituted). - 82 tests at 100% line coverage (enforced);
ruff select=ALL,ty, and
eof-fixerclean.
0.1.0
First public release of compose2pod: convert a Docker Compose file into a POSIX sh script that runs its services as a single Podman pod. Extracted from a CI-proven prototype; no prior versions, so nothing to migrate.
Feature
- Compose → single Podman pod.
compose2pod --target <service> --image <ci-image> [file]reads a compose document and emits a shell script that creates one pod (shared network namespace, no bridge), starts dependencies in topological order, gates startup on health by pollingpodman healthcheck run, runs the target service, copies out artifacts, and cleans up via anEXITtrap. - Supported compose subset.
image/build,command,environment/env_file, short-form bindvolumes,healthcheck(CMD / CMD-SHELL),depends_on(service_started/service_healthy/service_completed_successfully), and networkaliases(mapped to--add-host). Anything outside the subset raises a clearUnsupportedComposeError;ports/restart/stdin_open/ttyare ignored with a warning. - CLI and library API. Use the
compose2podcommand (orpython -m compose2pod), or importvalidate,emit_script,EmitOptions, andUnsupportedComposeError. - JSON always, YAML optional. The core reads compose-as-JSON with zero dependencies (
--format json, or pipeyq);pip install compose2pod[yaml]adds direct YAML input.
Why
CI runners often give unprivileged containers a read-only /proc/sys, so netavark can't create bridge networks (upstream declined: podman#20713 closed, netavark#910 unmerged), and there's no systemd to schedule podman healthchecks. docker compose and podman kube play can't work there. A single pod shares one netns (no bridge, no netavark), services reach each other over 127.0.0.1, and health-gated depends_on works via manual podman healthcheck run polling. No existing tool covered that combination.
Packaging
- Published to PyPI via Trusted Publishing:
pip install compose2pod(core, zero runtime dependencies) orpip install compose2pod[yaml](adds PyYAML). requires-python >=3.10,<4; tested on CPython 3.10–3.14. Typed (py.typed). MIT licensed.
Downstream
No action needed — first release, no public API predecessors.
Internals
- 78 tests at 100% line coverage (enforced);
ruff select=ALL,ty, andeof-fixerclean. - One known follow-up is tracked in
planning/deferred.md: hardening the pod-cleanuptrap's nested quoting for the library API path (unreachable from the CLI, which validates pod names).