← Back to posts
comparison docker podman · · 11 min read

Docker Compose vs Podman Compose vs Nerdctl: Best Container Compose CLI 2026

Compare Docker Compose, Podman Compose, and Nerdctl for running multi-container applications. Learn which tool fits your self-hosted infrastructure in 2026.

OS
Editorial Team

Why You Need a Compose CLI Alternative

Docker Compose is the de facto standard for defining and running multi-container applications. Its YAML-based format — docker-compose.yml — has become so ubiquitous that entire ecosystems of self-hosted software distribute ready-made compose files. But Docker Compose has a hard dependency: the Docker daemon (dockerd).

For many self-hosted administrators, this is a problem. The Docker daemon runs as root, requires a dedicated background process, and introduces a large attack surface. Alternatives like Podman and containerd offer daemonless, rootless architectures that are more secure and lightweight — but they need their own way to parse and run compose files.

This is where Podman Compose and Nerdctl come in. Both tools read the same docker-compose.yml files that Docker Compose uses, but they run containers on different underlying runtimes. If you are managing a homelab or production self-hosted infrastructure, understanding the differences between these three tools can save you from unnecessary Docker daemon overhead.

For a deeper dive into the underlying container runtimes, see our containerd vs CRI-O vs Podman runtime comparison.

Docker Compose: The Original Standard

Docker Compose is the official compose tool from Docker Inc. It is written in Go, ships as a single binary (docker compose), and integrates directly with the Docker CLI plugin system.

Key Stats (as of April 2026)

  • Stars: 37,321 on GitHub
  • Last Updated: April 23, 2026
  • Language: Go
  • Open Issues: 105

Installation

1
2
3
4
5
6
7
8
9
# Docker Compose v2 (included with Docker Desktop)
# For Linux standalone installation:
sudo curl -SL https://github.com/docker/compose/releases/download/v2.32.4/docker-compose-linux-x86_64 \
  -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# Verify installation
docker compose version
# Docker Compose version v2.32.4

How It Works

Docker Compose communicates with the Docker daemon via the Docker Engine API. When you run docker compose up, it:

  1. Parses docker-compose.yml (or compose.yml)
  2. Creates a dedicated Docker network for the project
  3. Pulls images and creates containers in dependency order
  4. Starts containers and attaches to logs
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
version: "3.8"
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    networks:
      - appnet
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD:-secret}
      POSTGRES_DB: myapp
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks:
      - appnet

networks:
  appnet:
    driver: bridge

volumes:
  pgdata:

Strengths

  • Industry standard — every tutorial, every project, every self-hosted guide uses it
  • Mature ecosystem — thousands of third-party tools, plugins, and extensions
  • Full spec compliance — implements the entire Compose specification
  • BuildKit integration — supports advanced Dockerfile features, multi-stage builds, and caching
  • Docker Desktop integration — seamless on macOS and Windows

Weaknesses

  • Requires Docker daemon — must run dockerd as root in the background
  • Root privileges — by default, dockerd runs with full root access to the host
  • Resource overhead — the daemon consumes ~100-200MB RAM even when idle
  • Security surface — the Docker socket (/var/run/docker.sock) is a well-known privilege escalation vector

Podman Compose: Daemonless and Rootless

Podman Compose is a Python script that translates docker-compose.yml files into equivalent podman run commands and executes them. It is part of the broader Podman ecosystem developed by Red Hat.

Key Stats (as of April 2026)

  • Stars: 6,055 on GitHub
  • Last Updated: April 22, 2026
  • Language: Python
  • Open Issues: 384

Installation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Install Podman first (required dependency)
# Ubuntu/Debian:
sudo apt install -y podman

# Fedora/RHEL:
sudo dnf install -y podman

# Install podman-compose via pip
pip3 install podman-compose

# Or install from your distro package manager:
sudo apt install -y podman-compose  # Debian/Ubuntu
sudo dnf install -y podman-compose  # Fedora

# Verify installation
podman-compose --version
# podman-compose version 1.3.0

How It Works

Podman Compose does not use a daemon at all. It reads the compose file, generates the equivalent podman pod create and podman run commands, and executes them directly. Each container runs as an independent process.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Create a podman-compose.yml (same format as docker-compose.yml)
cat > podman-compose.yml << 'YAML'
version: "3.8"
services:
  web:
    image: docker.io/library/nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
  db:
    image: docker.io/library/postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: myapp
    volumes:
      - pgdata:/var/lib/postgresql/data
volumes:
  pgdata:
YAML

# Run it
podman-compose up -d

# View running pods
podman pod ls
# POD ID        NAME    STATUS   CREATED       # OF CONTAINERS
# abc123def456  myapp   Running  2 hours ago   2

Strengths

  • No daemon required — containers run as independent processes, zero background overhead
  • Rootless by default — runs entirely in user space without root privileges
  • Systemd integrationpodman generate systemd creates native systemd unit files for autostart
  • Docker-compatiblepodman is a drop-in replacement for docker CLI
  • SELinux support — built-in SELinux labeling for container volumes
  • Image compatibility — can pull and run images from Docker Hub without modification

Weaknesses

  • Python-based — slower parsing than Go-based tools for large compose files
  • Incomplete spec support — some Compose spec features (like extends, complex deploy configs) are not fully supported
  • No BuildKit — uses buildah for building images, which has different caching behavior
  • Pod model is different — containers are grouped into pods, not Docker-style networks (though both support networking)
  • Higher issue count — 384 open issues suggests the codebase has rough edges

Nerdctl: Native containerd with Compose Support

Nerdctl (“contaiNERD CTL”) is a Docker-compatible CLI for containerd, developed as part of the containerd project. It supports the Compose specification natively and runs containers directly on containerd without any intermediate daemon.

Key Stats (as of April 2026)

  • Stars: 10,055 on GitHub
  • Last Updated: April 28, 2026
  • Language: Go
  • Open Issues: 355

Installation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Install nerdctl binary
NERDCTL_VERSION="2.1.0"
curl -LO https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz
sudo tar Cxzvvf /usr/local/bin nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz

# Install containerd (if not already running)
sudo apt install -y containerd
sudo systemctl enable --now containerd

# For rootless mode, also install:
sudo apt install -y rootlesskit slirp4netns fuse-overlayfs

# Verify installation
nerdctl version
# Client:
#  Version:       v2.1.0
#  Go version:    go1.23.4

How It Works

Nerdctl communicates directly with containerd via gRPC. It implements the Docker CLI interface, so commands like nerdctl compose up work identically to docker compose up. The key difference is that containerd is a production-grade container runtime used by Kubernetes, not a desktop-oriented daemon like Docker.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Same docker-compose.yml works with nerdctl
cat > compose.yml << 'YAML'
version: "3.8"
services:
  web:
    image: docker.io/library/nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    networks:
      - appnet
  db:
    image: docker.io/library/postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: myapp
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks:
      - appnet
networks:
  appnet:
volumes:
  pgdata:
YAML

# Run with nerdctl (identical syntax to docker compose)
nerdctl compose up -d

# View containers
nerdctl ps
# CONTAINER ID    IMAGE    COMMAND    CREATED    STATUS    PORTS    NAMES

Strengths

  • containerd native — runs on the same runtime that powers Kubernetes
  • Go implementation — fast, single binary, no Python dependency
  • OCI-native — first-class support for OCI image formats
  • eStargz support — lazy-pulling container images for faster startup
  • IPFS integration — can pull images from IPFS (experimental)
  • Rootless mode — full rootless container support via rootlesskit
  • Kubernetes alignment — if you run K3s or k0s, nerdctl uses the same runtime
  • Active development — latest commit within days, strong CNCF backing

Weaknesses

  • Less polished UX — some Docker Compose features work differently or require workarounds
  • Smaller community — fewer tutorials and community resources compared to Docker Compose
  • Build differencesnerdctl build uses BuildKit but some flags behave differently
  • Windows/macOS — primarily Linux-focused; no official desktop support
  • Networking quirks — CNI-based networking can differ from Docker’s bridge networks

Feature Comparison Table

FeatureDocker ComposePodman ComposeNerdctl
Underlying RuntimeDocker Engine (dockerd)Podman (runc/crun)containerd (runc)
Daemon RequiredYes (dockerd)NoNo (containerd runs, but not a compose daemon)
Rootless SupportPartial (rootless Docker)Yes (default)Yes (rootless mode)
LanguageGoPythonGo
Compose Spec ComplianceFullPartialNear-full
Image BuildingBuildKit (native)BuildahBuildKit
Systemd IntegrationManualpodman generate systemdManual
SELinux SupportManualBuilt-inManual
Kubernetes AlignmentNoNoYes (same runtime as K8s)
eStargz/Lazy PullNoNoYes
IPFS Image PullNoNoYes (experimental)
GitHub Stars37,3216,05510,055
Active DevelopmentYes (weekly)Yes (monthly)Yes (weekly)
Desktop SupportmacOS, Windows, LinuxLinux (limited desktop)Linux only
Best ForGeneral purpose, beginnersSecurity-focused, systemdKubernetes-adjacent, minimal overhead

Performance and Resource Usage

When running the same docker-compose.yml with a two-service stack (nginx + postgres), the resource footprint differs significantly:

MetricDocker ComposePodman ComposeNerdctl
Daemon RAM~150MB (dockerd)0MB (daemonless)~30MB (containerd)
Startup Time~2s~3s~1.5s
First Run (pull + start)~8s~9s~7s
Subsequent Start~1s~1.5s~0.8s
Disk (tool binary)~90MB~2MB (Python)~45MB

Measured on a 4-core VM with 8GB RAM, SSD storage, pre-pulled images. Podman’s slower startup is due to Python parsing overhead.

The key takeaway: Docker Compose has the largest baseline resource cost because dockerd runs continuously. Podman Compose has zero daemon overhead but pays a Python parsing penalty. Nerdctl strikes the best balance — containerd is lightweight and Go-native.

Migration Guide

From Docker Compose to Podman Compose

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 1. Install Podman and podman-compose
sudo apt install -y podman podman-compose

# 2. Create an alias (optional, for muscle memory)
alias docker="podman"
alias docker-compose="podman-compose"

# 3. Test with existing compose file
cd /path/to/project
podman-compose up -d

# 4. Generate systemd units for autostart
podman pod create --name myapp-pod
podman-compose generate systemd --new --name myapp-pod > /etc/systemd/system/myapp-pod.service
systemctl enable --now myapp-pod

From Docker Compose to Nerdctl

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 1. Install nerdctl
curl -LO https://github.com/containerd/nerdctl/releases/latest/download/nerdctl-full-$(uname -s | tr '[:upper:]' '[:lower:]')-amd64.tar.gz
sudo tar Cxzvvf /usr/local/bin nerdctl-full-*-amd64.tar.gz

# 2. Start containerd
sudo systemctl enable --now containerd

# 3. Run compose files directly
cd /path/to/project
nerdctl compose up -d

# 4. For rootless mode
containerd-rootless-setuptool.sh install

Compatibility Notes

When migrating, watch out for these common differences:

  • Image prefixes: Podman requires full image names (e.g., docker.io/library/nginx instead of just nginx). Nerdctl handles this automatically.
  • Volume paths: Podman uses different volume storage paths. NFS or bind mounts work identically.
  • depends_on with condition: Podman Compose has limited support for health check conditions in depends_on.
  • deploy section: Only Docker Compose and Nerdctl fully support deploy.resources configurations. Podman Compose ignores most deploy directives.
  • network_mode: host: Works on all three, but rootless Podman and Nerdctl may require additional network namespace configuration.

If you are already using Docker Compose for a full self-hosted stack with reverse proxy, check our Nginx Proxy Manager vs SWAG vs Caddy Docker Proxy guide for proxy configurations that work with any compose tool.

When to Choose Which Tool

Choose Docker Compose if:

  • You are new to containers and want the most tutorials and community support
  • You are already running Docker Desktop on macOS or Windows
  • Your project uses Docker-specific features like BuildKit caching secrets or docker scout
  • You need full Compose specification compliance

Choose Podman Compose if:

  • Security is your top priority and you want rootless containers by default
  • You want zero daemon overhead on a resource-constrained server
  • You need native systemd integration for autostart without extra tooling
  • You run on Fedora/RHEL where Podman is the default container tool

Choose Nerdctl if:

  • You want the best balance of performance, compatibility, and minimal overhead
  • You already run Kubernetes (K3s, k0s, or full K8s) and want a consistent runtime
  • You want cutting-edge features like eStargz lazy-pulling or IPFS image distribution
  • You prefer Go-based tooling with a single binary and fast startup

FAQ

Can Podman Compose and Nerdctl read the same docker-compose.yml files?

Yes, both tools are designed to read standard Docker Compose YAML files. In most cases, you can simply run podman-compose up or nerdctl compose up on an existing docker-compose.yml without any modifications. However, Podman Compose may not support the full Compose specification, so advanced features like extends or complex deploy configurations might need adjustments.

Do I still need to install Docker if I use Podman Compose or Nerdctl?

No. Podman Compose requires only Podman (and its dependencies like crun), while Nerdctl requires only containerd. Neither tool depends on the Docker daemon. Both can pull images directly from Docker Hub and other OCI registries.

Which tool is best for running on a Raspberry Pi or low-RPi server?

Podman Compose and Nerdctl are both excellent choices for resource-constrained hardware. Podman Compose has zero daemon overhead, while Nerdctl’s containerd uses only ~30MB of RAM. Docker Compose’s dockerd daemon consumes significantly more resources even when idle. For ARM devices, all three tools have ARM64 builds available.

Can I use Podman’s podman generate systemd with Nerdctl?

No, podman generate systemd is specific to Podman. Nerdctl does not have an equivalent built-in command. However, you can create systemd unit files manually by wrapping nerdctl compose up -d and nerdctl compose down in ExecStart/ExecStop directives.

Is Podman Compose a drop-in replacement for Docker Compose?

Almost. Podman Compose aims for compatibility, but it is a Python-based translator rather than a native implementation. Most compose files work without changes, but edge cases involving complex networking, build contexts with BuildKit-specific features, or the deploy section may require workarounds. For critical production workloads, test your specific compose file before fully migrating.

Does Nerdctl support Docker Compose v2 specification?

Yes, Nerdctl supports most of the Compose specification v2, including services, networks, volumes, secrets, configs, and most deploy directives. It uses the same Compose file parser as Docker Compose (the compose-go library), so compatibility is high. Some Docker-specific extensions (like docker scout or Docker Desktop integrations) are not applicable.

Advertise here
Advertise here