結論

Podmanは、常駐デーモンなしでコンテナを動かす、Docker互換のコンテナエンジンです。一般ユーザー権限(rootless)で動かせ、Pod もまとめて扱えます。

この記事でわかること

  • Dockerとの違い8項目と、コマンド対応表30行
  • rootless・Pod・compose・Quadletの実行結果
  • エラー原文12種と原因・直し方の表

2026年10月22日更新|Podman 4.9.3・Ubuntu 24.04で実行確認

Docker は CLI が常駐デーモン(dockerd)に頼んでコンテナを作ります。Podman は CLI 自身がコンテナを作り、見張り役の小さなプロセス(conmon)を残して終わります。

flowchart TD
    D[docker コマンド] --> DD[dockerd<br>root で常駐]
    DD --> R1[runc<br>コンテナ]
    P[podman コマンド<br>一般ユーザーでも可] --> C[conmon<br>コンテナごとの見張り]
    C --> R2[runc / crun<br>コンテナ]

急いでいる人向けに、よく調べられることの答えを先にまとめます。

知りたいこと 答え 詳しい節
Podmanとは デーモンなしのコンテナエンジン。読み方はポッドマン Podmanとは
Dockerとの違い デーモンなし・rootless が標準・Pod がある 違い
コマンドは? docker を podman に置き換えるとほぼ同じ 対応表
無料? Podman も Podman Desktop も無料のOSS FAQ
Windows・Mac Podman Desktop か podman machine で Linux VM を使う インストール
compose は? podman compose が外部の compose を呼ぶ compose
自動起動は? Quadlet(.container ファイル)で systemd に任せる Quadlet
最新版 Podman 6.1.4、Podman Desktop 1.30.5(2026年10月22日時点) インストール

確認環境:Ubuntu 24.04.4(カーネル 6.18)で、Ubuntu のパッケージの Podman 4.9.3(conmon 2.1.10・netavark 1.4.0・aardvark-dns 1.4.0・runc 1.3.5)を動かして確かめました。rootful(root)での実行と、一般ユーザー(UID 65534 の nobody)での rootless の実行の両方を試し、イメージは busybox から作った 3.31MB のものを podman import・podman build で用意しました。Docker CLI 29.4.3 と Docker Compose v5.1.3 を Podman の API につないだ結果も載せています。Podman 5・6 系の変更点、Mac・Windows・Podman Desktop の手順は、podman.io・docs.podman.io・podman-desktop.io・GitHub の containers/podman(RELEASE_NOTES.md とチュートリアル)で、最新版の番号は GitHub のリリースタグで確かめました(確認日 2026年10月22日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Podmanとは|Dockerとの違い・使い方とrootless・Quadlet実例」

Podmanとは(読み方・できること・開発元)

この節では、Podman が何をする道具で、誰が作っているのかが分かります。

Podman(ポッドマン、Pod Manager)は、コンテナとコンテナイメージ、Pod を作って動かすためのオープンソースのツールです。 Red Hat とコミュニティが開発し、Linux で動きます。Mac と Windows では、Podman が用意する Linux の仮想マシン(podman machine)の中で動きます。

  • Docker とほぼ同じコマンドで使えます。docker run は podman run、docker build は podman build です。
  • イメージの形式は共通です。Docker Hub などのレジストリにある OCI・Docker 形式のイメージをそのまま使えます。
  • 常駐するデーモンがありません。 コマンドを打ったユーザーの権限でコンテナが動きます。
  • Pod(複数のコンテナをまとめて、ネットワークなどを共有させる単位)を作れます。Kubernetes の Pod と同じ考え方です。

CNCF(Kubernetes などを持つ財団)のプロジェクトページでは、Podman・Buildah・Skopeo は「Podman Container Tools」として 2025年1月21日に Sandbox(初期段階)のプロジェクトとして受け入れられています。Podman Desktop も CNCF の Sandbox プロジェクトです。

Podman のまわりには、役割を分けたツールがあります。

1Podman

コンテナ・イメージ・Pod の操作の中心。docker と同じ形のコマンドと、Docker 互換の REST API を持つ。

2Buildah

イメージを作る道具。podman build の中身は Buildah で、4.9.3 の podman info にも buildahVersion 1.33.7 と出る。

3Skopeo

イメージをレジストリ間でコピーしたり、取り込まずに中身を調べたりする道具。

4Podman Desktop

Windows・Mac・Linux 用の画面のアプリ。Podman の導入、コンテナ・Pod・イメージの操作、Kubernetes との連携ができる。

PodmanとDockerの違い(デーモン・rootless・Pod)

この節では、Docker との違いを、仕組みと表の両方で確かめられます。

コンテナを作る仕組み

Dockerdocker コマンドは dockerd に API で頼むだけ。dockerd(通常は root)が止まると、全部のコンテナの操作ができなくなる
→
Podmanpodman コマンドが fork・exec でコンテナを作り、conmon を残して終わる。コンテナの親は conmon で、デーモンを経由しない

Podman にも API はあるが、使うときだけ podman system service で起動する

項目 Docker(Docker Engine) Podman
常駐デーモン dockerd が常に動く なし(API が要るときだけ起動)
既定の権限 root のデーモン(rootless モードもある) 打ったユーザーの権限。rootless が基本
Pod なし(compose でまとめる) podman pod で作れる
Kubernetes の YAML 出力しない podman kube generate・play
自動起動 --restart とデーモン systemd に任せる(Quadlet)
compose docker compose が付属 podman compose が外部の compose を呼ぶ
画面のアプリ Docker Desktop Podman Desktop
料金 Docker Desktop は大きな組織の仕事で有料 Podman・Podman Desktop とも無料

Docker Desktop が無料なのは、Docker の公式ドキュメントによると個人利用・教育・営利でないオープンソース・「従業員250人未満かつ年間売上1,000万ドル未満」の小さな会社です(2026年10月22日時点)。それより大きい組織の仕事では、Pro・Team・Business の契約が要ります。Docker Engine 自体のライセンスはこれとは別です。Docker Desktop の条件と使い方は、関連記事「Docker Desktopとは|インストール・使い方・有料の条件とエラー対処」で扱っています。

デーモンが無いことを実物で見る

Podman 4.9.3 で sleep 300 のコンテナを rootless で起動し、ホスト側の ps で親子関係を見ました。

$ ps -eo user,pid,ppid,comm | grep nobody
nobody    6463     1 podman pause
nobody    6730     1 conmon
nobody    6786     1 conmon
nobody    6796  6786 sleep

sleep の親は conmon で、どちらも一般ユーザー(nobody)のプロセスです。 podman コマンドはもう終わっていて、root で動くデーモンはどこにもありません。podman pause は rootless のときにユーザーの名前空間を保っておくための小さなプロセスです。

rootlessとは(ユーザー名前空間の仕組み)

この節では、rootless のコンテナの中の root が、ホストではただの一般ユーザーになる仕組みを、出力で確かめられます。

rootless は、一般ユーザーがコンテナを動かし、コンテナの中の root(UID 0)をホストのそのユーザーに対応させる方式です。 Linux の「ユーザー名前空間」で UID を付け替えています。コンテナから抜け出されても、ホストではそのユーザーの権限しかありません。

$ id
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)

$ podman run --rm --network none localhost/bb:1 sh -c "id; cat /proc/self/uid_map"
uid=0(root) gid=0(root)
         0      65534          1

$ podman top sleeper user huser pid comm
USER        HUSER       PID         COMMAND
root        nobody      1           sleep

uid_map の「0 65534 1」は「コンテナの UID 0 から1個分を、ホストの UID 65534 に対応させる」という意味です。podman top の USER(コンテナの中のユーザー)は root、HUSER(ホストのユーザー)は nobody です。

同じことを root で(rootful で)動かすと、こうなりました。

# podman top s1 user huser pid comm
USER        HUSER       PID         COMMAND
root        root        1           sleep

# podman top web user huser pid comm      ← Containerfile に USER nobody と書いたイメージ
USER        HUSER       PID         COMMAND
nobody      nobody      1           httpd

rootful では、コンテナの root はホストでも root です。 rootful でも Containerfile の USER で一般ユーザーに切り替えると、ホスト側も一般ユーザーになります。

subuid・subgid の設定(rootless の準備)

コンテナのイメージには、root 以外に複数のユーザー(UID 1 以降)が入っていることがよくあります。rootless でそれらを使うには、ユーザーごとに「借りてよい UID の範囲」を /etc/subuid・/etc/subgid に書きます。範囲が無いユーザーで実行すると、次のメッセージが出ました。

level=error msg="cannot find UID/GID for user nobody: no subuid ranges found for user \"nobody\" in /etc/subuid - check rootless mode in man pages."
level=warning msg="Using rootless single mapping into the namespace. This might break some images. Check /etc/subuid and /etc/subgid for adding sub*ids if not using a network user"

UID が1個しか対応しない「single mapping」で動くので、root だけで動くイメージは動きますが、ほかのユーザーのファイルを含むイメージは壊れることがあります。Podman の rootless のチュートリアルでは、次のように設定します。

# /etc/subuid と /etc/subgid の書式は「ユーザー名:開始ID:個数」
# 例:johndoe:100000:65536

# 直接編集する代わりに usermod で足す(管理者が実行)
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 johndoe

# 設定を変えたら、そのユーザーで実行して pause プロセスなどを作り直す
podman system migrate

# 確かめる
podman unshare cat /proc/self/uid_map

ユーザーごとの範囲は重ならないようにします。チュートリアルでは、重なると別のユーザーの名前空間を壊すおそれがあると説明しています。また、NIS・LDAP などのネットワーク上のユーザーでも、subuid・subgid はローカルのファイルに要ります。

  • 1/etc/subuid・/etc/subgid に自分の範囲がある無いと single mapping になり、一部のイメージが壊れる
  • 2newuidmap・newgidmap があるDebian・Ubuntu では uidmap パッケージ。Podman の依存で入る
  • 3ネットワーク用の pasta(passt)か slirp4netns があるPodman 5 以降の既定は pasta。6.0 で slirp4netns は削除
  • 4/dev/net/tun を一般ユーザーが開ける開けないと pasta・slirp4netns が Permission denied で止まる
  • 51024 未満のポートを使うなら sysctl を変えるnet.ipv4.ip_unprivileged_port_start(既定 1024)
  • 6cgroups v2 で動いているPodman 6.0 で cgroups v1 のサポートは削除

rootless で起きやすい制限

rootless のコンテナは、ネットワークを pasta(Podman 5 以降の既定)か slirp4netns(Podman 4 までの既定)という、ユーザー権限で動くネットワークの仕組みでつなぎます。どちらも /dev/net/tun を使うので、一般ユーザーが開けない環境では次のように止まりました。

$ podman run --rm localhost/bb:1 true        # Podman 4.9.3 の既定(slirp4netns)
Error: /usr/bin/slirp4netns failed: "open(\"/dev/net/tun\"): Permission denied\n..."

$ podman run --rm --network pasta localhost/bb:1 true
Error: pasta failed with exit code 1:
...
Failed to open() /dev/net/tun: Permission denied
Failed to set up tap device in namespace

ネットワークが要らない処理なら --network none で動きます(上の rootless の出力は --network none で実行したものです)。

1024 未満のポート(80・443 など)は、Linux では一般ユーザーが待ち受けできません。Podman 4.9.3 の rootlessport には次のメッセージが入っています(%d に数字が入ります)。

cannot expose privileged port %d, you can add 'net.ipv4.ip_unprivileged_port_start=%d' to /etc/sysctl.conf (currently %d)

直し方は3つです。8080 など 1024 以上のポートにする、管理者が net.ipv4.ip_unprivileged_port_start=80 を設定する、rootful(sudo podman)で動かす、のどれかです。

Podmanのインストール(Linux・Mac・Windows・Podman Desktop)

この節では、OS ごとの入れ方と、入ったことの確かめ方が分かります。

Linux

podman.io のインストール手順のコマンドです。Linux では仮想マシンを使わず、そのまま動きます。

ディストリビューション コマンド
Ubuntu 20.10 以降・Debian 11 以降 sudo apt-get -y install podman
Fedora・CentOS Stream 9 以降 sudo dnf -y install podman
RHEL Red Hat のドキュメントの手順(RHEL のリポジトリに含まれる)
Arch Linux・Manjaro sudo pacman -S podman
Alpine Linux sudo apk add podman
openSUSE sudo zypper install podman
Fedora CoreOS・Silverblue 最初から入っている

ディストリビューションのパッケージは、最新版より前の版のことがあります。 Ubuntu 24.04 の apt で入るのは 4.9.3 で、GitHub の最新は 6.1.4 です(2026年10月22日時点)。版によって使える機能が違うので、入れたら版を確かめます。

$ podman --version
podman version 4.9.3

$ podman info        # 抜粋
host:
  buildahVersion: 1.33.7
  cgroupManager: cgroupfs
  cgroupVersion: v1
  conmon:
    version: 'conmon version 2.1.10, commit: unknown'
  databaseBackend: sqlite
  networkBackend: netavark
  ociRuntime:
    name: runc
  security:
    rootless: true
  store:
    graphDriverName: overlay
    graphRoot: /home/user/.local/share/containers/storage

rootless のイメージやコンテナは ~/.local/share/containers/storage、root のものは /var/lib/containers/storage に置かれます。同じマシンでも、root と一般ユーザーではイメージもコンテナも別々です。

Mac

podman.io の手順では、公式サイトか GitHub のリリースにあるインストーラー(pkg)を使います。Homebrew(brew install podman)もありますが、公式は「コミュニティが管理するもので安定性は保証されない」として推奨していません。入れたら Linux の仮想マシンを作って起動します。

podman machine init
podman machine start
podman info

Podman 6.0 のリリースノートによると、6.0 で Intel の Mac はサポート対象から外れ、Mac の仮想マシンの既定の仕組み(provider)は libkrun になりました。

Windows

Windows も Linux の仮想マシンの中で Podman を動かします。仮想マシンの仕組みは WSL 2 か Hyper-V です。

1

WSL を有効にする

PowerShell で wsl --update と wsl --install --no-distribution を実行し、再起動する。

2

Podman を入れる

GitHub のリリースにある Windows 用インストーラーか、Podman Desktop の初回設定から入れる。

3

仮想マシンを作る

podman machine init。最小構成の Fedora が入り、Podman 用に設定される。

4

起動して確かめる

podman machine start のあと podman info。既定は rootless で動く。

Podman の Windows 用ガイドでは、起動後は Docker API のパイプ npipe:////./pipe/docker_engine で待ち受けます。80 番など 1024 未満のポートを使うときは、podman machine stop のあと podman machine set --rootful で rootful に切り替えます。Podman 6.0 のリリースノートでは、Windows 10 はサポート対象から外れ、Hyper-V の仮想マシンの起動・停止に管理者権限が要らなくなりました(新しく作った仮想マシンのみ)。

Linux で podman machine init を打つと、仮想マシンを作る QEMU が無い環境では次のエラーになりました。Linux ではふつう仮想マシンは要りません。

$ podman machine init
Error: exec: "qemu-system-x86_64": executable file not found in $PATH
# root で打った場合
Error: cannot run command "podman machine init" as root

Podman Desktop

Podman Desktop は、Podman を画面で操作するアプリです。Apache License 2.0 のオープンソースで、最新は 1.30.5 です(2026年10月22日時点、GitHub のリリースタグ)。

OS 入れ方 要件(公式ドキュメント)
Windows インストーラー・winget install RedHat.Podman-Desktop・Chocolatey・Scoop 64ビット、Podman 用に RAM 6GB、WSL 2 は Windows 10 19043 以降か 11
Mac .dmg(ユニバーサル版)・brew install --cask podman-desktop Apple シリコン・Intel のどちらの .dmg もある
Linux Flatpak(io.podman_desktop.PodmanDesktop) Podman 本体は別に入れる

初めて起動すると「Get started with Podman Desktop」の画面から Start Onboarding が始まり、Podman のインストール、Podman マシンの作成、kubectl と compose の CLI の導入が順に案内されます。Settings の Resources で Podman マシンが動いていれば準備完了です。

Podman を CLI で使う

Linux はパッケージを入れるだけ

Mac・Windows は podman machine init / start

サーバー・CI・スクリプトに向く

Podman Desktop を使う

Podman・マシン・compose・kubectl を画面の案内で入れる

コンテナ・Pod・イメージ・ボリュームを画面で操作

Kind・Minikube などの Kubernetes も扱える

Podmanの使い方(基本のコマンド)

この節では、イメージの取得・ビルド・起動・確認・削除の流れを、実際の出力で追えます。

イメージを取得する(短い名前に注意)

podman pull docker.io/library/nginx:latest   # レジストリまで書いた完全な名前
podman pull nginx                            # 短い名前(設定しだいで失敗する)

Podman では、nginx のような短い名前をどのレジストリから取るかが、registries.conf の設定で決まります。 Ubuntu のパッケージの registries.conf は検索先が空なので、短い名前は次のエラーになりました。

$ podman pull nginx
Error: short-name "nginx" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"

直し方は、docker.io/library/nginx のように完全な名前で書くか、/etc/containers/registries.conf(ユーザーごとなら ~/.config/containers/registries.conf)に検索先を書くことです。

unqualified-search-registries = ["docker.io"]

Containerfile(Dockerfile)の FROM や Quadlet の Image= でも、完全な名前を書いておくと、どの環境でも同じイメージが取れます。

ビルドして起動する

Podman は Containerfile という名前を優先して探し、無ければ Dockerfile を使います。中身の書き方は Dockerfile と同じです。

FROM localhost/bb:1
COPY index.html /www/index.html
EXPOSE 8080
USER nobody
CMD ["httpd", "-f", "-p", "8080", "-h", "/www"]
$ podman build -t localhost/myapp:1.0 .
STEP 1/5: FROM localhost/bb:1
STEP 2/5: COPY index.html /www/index.html
--> 7f66f4e7ebeb
STEP 3/5: EXPOSE 8080
--> 46b460cc0a51
STEP 4/5: USER nobody
--> 409adf9d47f2
STEP 5/5: CMD ["httpd", "-f", "-p", "8080", "-h", "/www"]
COMMIT localhost/myapp:1.0
--> fb71e3b15d87
Successfully tagged localhost/myapp:1.0
fb71e3b15d8797f459b97d504e60d82f8f5f6db0e421917976ed749b8d0d7f75

$ podman images
REPOSITORY          TAG         IMAGE ID      CREATED                 SIZE
localhost/myapp     1.0         fb71e3b15d87  Less than a second ago  3.31 MB
localhost/bb        1           787f726efb5e  3 minutes ago           3.31 MB

$ podman run -d --name web -p 8080:8080 localhost/myapp:1.0
61f7d33e12e3378dc5f9d10426b0da51fd156deb27deffd13c2306e10aff04eb

$ podman ps
CONTAINER ID  IMAGE                COMMAND               CREATED       STATUS       PORTS                   NAMES
61f7d33e12e3  localhost/myapp:1.0  httpd -f -p 8080 ...  1 second ago  Up 1 second  0.0.0.0:8080->8080/tcp  web

$ curl http://127.0.0.1:8080/
<h1>myapp v1</h1>

$ podman port web
8080/tcp -> 0.0.0.0:8080

ビルドした名前に localhost/ が付くのが Podman の特徴です。レジストリを書かずにタグを付けると、Podman は localhost/ のイメージとして扱います。Containerfile の書き方は、関連記事「Dockerfileの書き方|軽く・速く・安全なイメージを作るベストプラクティス」で扱っています。

名前で通信する(ネットワーク)

既定のネットワーク(podman)では、コンテナ名で相手を引けません。 自分で作ったネットワークでは、aardvark-dns がコンテナ名を IP アドレスに変換します。

$ podman network create mynet
mynet
$ podman run -d --name api --network mynet localhost/myapp:1.0
$ podman run --rm --network mynet localhost/bb:1 nslookup api
Server:     10.89.1.1
Address:    10.89.1.1:53

Non-authoritative answer:
Name:   api.dns.podman
Address: 10.89.1.2

$ podman run --rm --network mynet localhost/bb:1 wget -qO- http://api:8080/
<h1>myapp v1</h1>

$ podman run --rm localhost/bb:1 wget -qO- -T 2 http://api:8080/     # 既定のネットワーク
wget: bad address 'api:8080'

$ podman network ls
NETWORK ID    NAME                         DRIVER
c91df35415db  mynet                        bridge
2f259bab93aa  podman                       bridge
d08a8fd32ffa  podman-default-kube-network  bridge

Docker でも既定の bridge ネットワークでは名前が引けず、自分で作ったネットワークで引ける点は同じです。Podman 6.0 のリリースノートでは、ネットワークの機能は netavark だけになり(CNI は削除)、ファイアウォールは nftables を使います(iptables は削除)。

dockerコマンドとPodmanの対応表

この節では、Docker のコマンドを Podman でどう書くかと、Podman だけのコマンドが一目で分かります。

やりたいこと Docker Podman
イメージを取得 docker pull podman pull
コンテナを起動 docker run -d -p 8080:80 podman run -d -p 8080:80
動いているものを一覧 docker ps podman ps
止まったものも一覧 docker ps -a podman ps -a
ログを見る docker logs -f podman logs -f
中でコマンド docker exec -it web sh podman exec -it web sh
止める・消す docker stop・docker rm podman stop・podman rm
イメージを作る docker build -t app . podman build -t app .
イメージ一覧・削除 docker images・docker rmi podman images・podman rmi
タグ・プッシュ docker tag・docker push podman tag・podman push
ログイン docker login podman login
ボリューム docker volume create podman volume create
ネットワーク docker network create podman network create
詳しく見る docker inspect podman inspect
使用量 docker stats podman stats
ファイルをコピー docker cp podman cp
保存・読み込み docker save・docker load podman save・podman load
掃除 docker system prune podman system prune
情報 docker info podman info
compose docker compose up -d podman compose up -d
Pod を作る (なし) podman pod create
Pod の一覧 (なし) podman pod ps
K8s の YAML を出す (なし) podman kube generate
K8s の YAML で起動 (なし) podman kube play
systemd で動かす (なし) Quadlet の .container
名前空間の中で実行 (なし) podman unshare
自動でイメージ更新 (なし) podman auto-update
仮想マシンの管理 Docker Desktop が管理 podman machine
API を起動 dockerd が常に提供 podman system service
docker と打って使う ― alias docker=podman か podman-docker

Docker のコマンドの使い方は、関連記事「Dockerコマンド早見表|よく使う操作とつながらない時の対処」で扱っています。

docker と打っても Podman が動くようにする

いちばん簡単なのはシェルの別名です。毎回使うなら ~/.bashrc や ~/.zshrc に書きます。

alias docker=podman

Fedora・RHEL などには podman-docker というパッケージがあり、入れると docker と打ったときに Podman が動きます(Red Hat の説明)。

Docker CLI・ツールから Podman の API を使う

Podman は Docker 互換の REST API を持っています。podman system service で API を起動し、DOCKER_HOST をそのソケットに向けると、Docker CLI や Docker の API を使うツールが Podman につながります。 Docker CLI 29.4.3 から rootful の Podman 4.9.3 につなぎました。

# podman system service --time=0 &
# ls -l /run/podman/podman.sock
srw------- 1 root root 0 Oct 23 05:46 /run/podman/podman.sock

# export DOCKER_HOST=unix:///run/podman/podman.sock
# docker version --format "client={{.Client.Version}} api={{.Client.APIVersion}} server={{(index .Server.Components 0).Name}} {{.Server.Version}}"
client=29.4.3 api=1.41 server=Podman Engine 4.9.3

# docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
NAMES     IMAGE                 STATUS
web       localhost/myapp:1.0   Up 23 seconds
api       localhost/myapp:1.0   Up 10 seconds
s1        localhost/bb:1        Up 3 seconds

# docker run --rm localhost/bb:1 echo "docker CLI -> Podman API"
docker CLI -> Podman API

# curl --unix-socket /run/podman/podman.sock http://d/_ping
OK

Docker CLI は API の版を 1.41 に下げてつないでいます(Podman 4.9.3 の互換 API は 1.41)。Podman 6.0 で互換 API は Docker の v1.44 に上がりました。ソケットの場所は、rootful が /run/podman/podman.sock、rootless が $XDG_RUNTIME_DIR/podman/podman.sock(ふつうは /run/user/<UID>/podman/podman.sock)です。systemd があるマシンでは systemctl --user enable --now podman.socket で、使うときだけ API を起動できます。

podman podの使い方(Podとは)

この節では、Pod の中のコンテナが localhost で通信できることを、実際の出力で確かめられます。

Pod は、ネットワーク(IP アドレスとポート)などを共有するコンテナのまとまりです。 Pod を作ると「インフラコンテナ」が1つでき、Pod の名前空間を持ち続けます。後から入れたコンテナは、その名前空間に参加します。

flowchart TD
    H[ホストの 8081 番] --> I[インフラコンテナ<br>ネットワークを持つ]
    I --> W[app-web<br>80 番で待ち受け]
    I --> C[client<br>localhost:80 に接続]
# podman volume create webdata
# podman run --rm -v webdata:/www localhost/bb:1 sh -c "echo hello from pod > /www/index.html"
# podman pod create --name app -p 8081:80 --infra-image localhost/pause-bb
095d65007c54a890aa4e598b201d2e2eed2d1e55d103497a79a23265a93449a0
# podman run -d --pod app --name app-web -v webdata:/www:ro localhost/bb:1 httpd -f -p 80 -h /www
# podman run --rm --pod app localhost/bb:1 wget -qO- http://localhost:80/
hello from pod

# podman pod ps
POD ID        NAME        STATUS      CREATED                 INFRA ID      # OF CONTAINERS
095d65007c54  app         Running     Less than a second ago  49bc5d066631  2

# podman ps -a --pod --format "table {{.ID}} {{.Names}} {{.Status}} {{.Ports}} {{.PodName}}"
CONTAINER ID  NAMES               STATUS                 PORTS                   PODNAME
61f7d33e12e3  web                 Up 2 seconds           0.0.0.0:8080->8080/tcp  
49bc5d066631  095d65007c54-infra  Up Less than a second  0.0.0.0:8081->80/tcp    app
b58199ef3821  app-web             Up Less than a second  0.0.0.0:8081->80/tcp    app

# curl http://127.0.0.1:8081/
hello from pod

client のコンテナは localhost:80 で app-web に届きました。 Pod のコンテナは同じネットワークの名前空間にいるためです。ポートの公開(-p)は Pod を作るときに指定し、中のコンテナには書きません。--infra-image はインフラコンテナに使うイメージを指定するオプションで、指定しなければ Podman が用意する pause のイメージ(catatonit を動かすもの)を使います。

Pod から Kubernetes の YAML を作る・YAML で起動する

# podman kube generate app
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-4.9.3
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2026-10-23T05:44:31Z"
  labels:
    app: app
  name: app
spec:
  containers:
  - command:
    - httpd
    - -f
    - -p
    - "80"
    - -h
    - /www
    image: localhost/bb:1
    name: app-web
    ports:
    - containerPort: 80
      hostPort: 8081
    volumeMounts:
    - mountPath: /www
      name: webdata-pvc
      readOnly: true
  volumes:
  - name: webdata-pvc
    persistentVolumeClaim:
      claimName: webdata
      readOnly: true

名前付きボリュームは persistentVolumeClaim として出力されました。この YAML を保存して、Pod を消してから podman kube play で起動し直せます。

# podman kube generate app > app.yaml
# podman pod rm -f -t 0 app
# podman kube play app.yaml
Pod:
5c87f4bfefc3f6b1b1451d57f73942a6378a64d3d4d9b88ac7b77caba92cfa24
Container:
084aede52dd9367e449e96c5437d019663fd4ea594a2e2bcda88a8a87b910a7f

# curl http://127.0.0.1:8081/
hello from pod

# podman kube down app.yaml
Pods stopped:
5c87f4bfefc3f6b1b1451d57f73942a6378a64d3d4d9b88ac7b77caba92cfa24
Pods removed:
5c87f4bfefc3f6b1b1451d57f73942a6378a64d3d4d9b88ac7b77caba92cfa24

ローカルで試した構成を Kubernetes に持っていくときの下書きになります。Podman 6.1 では、ヘルスチェックが livenessProbe として出力されるようになりました。Kubernetes の Pod や Deployment の書き方は、関連記事「Kubernetes入門|主要リソースとYAMLの書き方、kubectl早見表」で扱っています。

podman composeの使い方(compose.yamlを動かす)

この節では、Docker の compose.yaml を Podman で動かす方法と、どの compose が使われるかが分かります。

podman compose は、compose の本体を持たない「呼び出し役」です。 docs.podman.io によると、外部の compose(プロバイダー)を探して、オプションをそのまま渡します。探す順番は docker-compose → podman-compose で、両方あれば docker-compose が使われます。

プロバイダー 何か 入れ方の例
docker-compose Docker Compose(Compose 仕様の元の実装) Docker の compose プラグイン、Podman Desktop の案内
podman-compose Python で書かれた Podman 用の compose pip install podman-compose(最新は 1.6.0)

プロバイダーは、環境変数 PODMAN_COMPOSE_PROVIDER か、containers.conf の [engine] の compose_providers で指定できます。指定したものが無いと、次のエラーになりました。

$ PODMAN_COMPOSE_PROVIDER=podman-compose podman compose up -d
>>>> Executing external compose provider "podman-compose". Please refer to the documentation for details. <<<<

Error: executing podman-compose up -d: exec: "podman-compose": executable file not found in $PATH

docker-compose(Docker Compose v5.1.3)が入っている環境で、2つのサービスの compose.yaml を動かしました。

services:
  web:
    image: localhost/myapp:1.0
    ports:
      - "8082:8080"
  checker:
    image: localhost/bb:1
    command: ["sh", "-c", "sleep 1; wget -qO- http://web:8080/"]
    depends_on:
      - web
$ podman compose up -d
>>>> Executing external compose provider "/usr/libexec/docker/cli-plugins/docker-compose". Please refer to the documentation for details. <<<<
 Network myapp_default Creating 
 Network myapp_default Created 
 Container myapp-web-1 Creating 
 Container myapp-web-1 Created 
 Container myapp-checker-1 Creating 
 Container myapp-checker-1 Created 
 Container myapp-web-1 Starting 
 Container myapp-web-1 Started 
 Container myapp-checker-1 Starting 
 Container myapp-checker-1 Started 

$ podman logs myapp-checker-1
<h1>myapp v1</h1>

$ curl http://127.0.0.1:8082/
<h1>myapp v1</h1>

$ podman compose down
 Container myapp-web-1 Removed 
 Network myapp_default Removed 

checker のコンテナは、サービス名 web で相手に届きました。 compose が作るネットワークでは、サービス名で名前が引けます。先頭の >>>> Executing external compose provider の行は、外部のコマンドを呼んでいることを知らせる表示で、containers.conf の compose_warning_logs = false で消せます(docs.podman.io)。compose.yaml の書き方は、関連記事「Docker Composeの使い方|compose.yamlの書き方と開発環境の作り方」で扱っています。

QuadletでPodmanのコンテナをsystemdで自動起動する

この節では、コンテナを OS の起動時に立ち上げ、落ちたら再起動させる設定と、その中身が分かります。

Quadlet は、.container などの短い設定ファイルから、systemd のサービス(.service)を自動で作る仕組みです。 Podman にはデーモンが無いので、自動起動や再起動は systemd に任せます。

flowchart TD
    Q[myapp.container<br>Quadlet のファイル] --> G[daemon-reload で<br>ジェネレーターが変換]
    G --> S[myapp.service]
    S --> R[podman run<br>で起動・再起動]

置き場所とファイルの種類

使う人 置き場所(主なもの)
root(システム全体) /etc/containers/systemd/
一般ユーザー ~/.config/containers/systemd/
一般ユーザー(管理者が置く) /etc/containers/systemd/users/
試すだけ(root) /run/containers/systemd/

ファイルの種類は、.container(コンテナ1つ)、.pod(Pod)、.volume(ボリューム)、.network(ネットワーク)、.kube(Kubernetes の YAML)、.image(イメージの取得)、.build(イメージのビルド)などです。Podman 4.9.3 で .pod のファイルを置いても変換されなかったので、使える種類は版で違います(.pod は 5 系で入りました)。

.container ファイルの例と、変換された .service

# ~/.config/containers/systemd/myapp.container
[Unit]
Description=myapp (Podman Quadlet)

[Container]
Image=localhost/myapp:1.0
ContainerName=myapp
PublishPort=8080:8080
Environment=TZ=Asia/Tokyo
AutoUpdate=registry

[Service]
Restart=always

[Install]
WantedBy=default.target

どんな .service になるかは、ジェネレーターを -dryrun で動かすと確かめられます。Podman 4.9.3 の quadlet で変換した結果です(podman-system-generator --user --dryrun でも同じものが見られます)。

$ /usr/libexec/podman/quadlet -dryrun -user
quadlet-generator[6448]: Loading source unit file /home/user/.config/containers/systemd/myapp.container
---myapp.service---
[Unit]
Description=myapp (Podman Quadlet)
SourcePath=/home/user/.config/containers/systemd/myapp.container
RequiresMountsFor=%t/containers

[X-Container]
Image=localhost/myapp:1.0
ContainerName=myapp
PublishPort=8080:8080
Environment=TZ=Asia/Tokyo
AutoUpdate=registry

[Service]
Restart=always
Environment=PODMAN_SYSTEMD_UNIT=%n
KillMode=mixed
ExecStop=/usr/bin/podman rm -v -f -i --cidfile=%t/%N.cid
ExecStopPost=-/usr/bin/podman rm -v -f -i --cidfile=%t/%N.cid
Delegate=yes
Type=notify
NotifyAccess=all
SyslogIdentifier=%N
ExecStart=/usr/bin/podman run --name=myapp --cidfile=%t/%N.cid --replace --rm --cgroups=split --sdnotify=conmon -d --label io.containers.autoupdate=registry --publish 8080:8080 --env TZ=Asia/Tokyo localhost/myapp:1.0

[Install]
WantedBy=default.target

[Container] の各行が、podman run のオプション(--publish・--env・--label io.containers.autoupdate=registry)に変わっています。 --rm と --replace が付くので、サービスを止めるとコンテナは消え、起動のたびに作り直されます。データを残すときは Volume= で名前付きボリュームを使います。

Image= の無いファイルは、次のエラーで変換されませんでした。

quadlet-generator[6448]: converting "bad.container": no Image or Rootfs key specified

起動と自動起動

# 一般ユーザーの場合(root なら --user を外し、/etc/containers/systemd/ に置く)
systemctl --user daemon-reload          # .container から .service が作られる
systemctl --user start myapp.service
systemctl --user status myapp.service
journalctl --user -u myapp.service

# ログアウトしてもユーザーのサービスを動かし続ける
loginctl enable-linger $USER

docs.podman.io によると、Quadlet が作るサービスは一時的なものなので systemctl enable は使えません。自動起動は [Install] の WantedBy= で指定し、ジェネレーターが生成のときに反映します。systemctl --user で動かす一般ユーザーのサービスは、ログアウトすると止まるので、loginctl enable-linger を設定しておきます(systemd の機能)。systemd の unit ファイルの項目は、関連記事「systemdサービス登録|本番用unitファイル雛形と設定項目の意味」で扱っています。

podman generate systemd との違い

以前は podman generate systemd で .service を書き出していました。4.9.3 でも動きますが、次の表示が出ます。

# podman generate systemd --name rootful-sleep

DEPRECATED command:
It is recommended to use Quadlets for running containers and pods under systemd.

Please refer to podman-systemd.unit(5) for details.

これから作るなら Quadlet を使います。AutoUpdate=registry を付けたコンテナは、podman auto-update でレジストリの新しいイメージに更新され、起動に失敗すると前のイメージに戻されます。

Podmanのよくあるエラーと直し方

この節では、Podman で出やすいエラーの原文から、原因と直し方を引けます。原文は Podman 4.9.3 で実際に出たものです。

エラー(原文の要部) 原因 直し方
short-name "nginx" did not resolve to an alias and no unqualified-search registries are defined 短い名前の検索先が無い docker.io/library/nginx と書くか registries.conf に検索先
no subuid ranges found for user /etc/subuid に範囲が無い usermod --add-subuids と podman system migrate
Using rootless single mapping into the namespace UID が1個しか対応しない 上と同じ(subuid・subgid を設定)
"/" is not a shared mount / のマウント伝播が private mount --make-rshared /(WSL・コンテナ内で出やすい)
slirp4netns failed: open("/dev/net/tun"): Permission denied 一般ユーザーが tun を開けない /dev/net/tun の権限、--network none
Failed to open() /dev/net/tun(pasta) 同上(pasta の場合) 同上
cannot expose privileged port 80 rootless で 1024 未満のポート 8080 等にするか ip_unprivileged_port_start
bind: address already in use ホストのポートが使用中 別のポートにするか、使っている側を止める
the container name "p1" is already in use 同じ名前のコンテナがある podman rm p1 か --replace を付ける
cannot remove container ... as it is running 動いているコンテナを消そうとした podman stop してから rm、か rm -f
image is in use by a container イメージを使うコンテナがある コンテナを消してから rmi、か rmi -f
executable file not found in $PATH(compose) compose のプロバイダーが無い docker-compose か podman-compose を入れる

実際の出力の例です。

# podman run -d --name p2 -p 34505:80 localhost/bb:1 httpd -f -p 80
Error: cannot listen on the TCP port: listen tcp4 :34505: bind: address already in use

# podman run -d --name p1 localhost/bb:1 sleep 1
Error: creating container storage: the container name "p1" is already in use by ebeabc49c7b1f03a9714ef508211cafd8e090f725abc523f25b2e0ebeaf78654. You have to remove that container to be able to reuse that name: that name is already in use, or use --replace to instruct Podman to do so.

# podman rm rootful-sleep
Error: cannot remove container 2484e9356b71b164d6ae3538aef35bba25581aca43d79d5f780b61ad206c4962 as it is running - running or paused containers cannot be removed without force: container state improper

# podman rmi localhost/bb:1
Error: image used by 2484e9356b71b164d6ae3538aef35bba25581aca43d79d5f780b61ad206c4962: image is in use by a container: consider listing external containers and force-removing image

ほかに、次のような場面も起こります。

  • 社内のプロキシやファイアウォールでレジストリへの通信が止められていると、pinging container registry registry-1.docker.io: Get "https://registry-1.docker.io/v2/": Forbidden のように、レジストリへの最初の接続で失敗します。HTTPS_PROXY の設定か、社内のレジストリ(ミラー)を registries.conf に書きます。
  • Mac・Windows で Cannot connect to Podman と出るときは、Linux の仮想マシンが止まっています。Podman 4.9.3 の文言は「Please verify your connection to the Linux system using podman system connection list, or try podman machine init and podman machine start」です。podman machine list で状態を見て、podman machine start で起動します。
  • Docker 用のツールが Podman につながらないときは、DOCKER_HOST が Podman のソケットを指しているか、podman system service(か podman.socket)が動いているかを確かめます。Docker のデーモンにつながらないときの切り分けは、関連記事「Cannot connect to the Docker daemonの原因と直し方」で扱っています。

PodmanとDocker、どちらを選ぶか(判断表)

この節では、自分の状況でどちらが合うかを判断できます。

状況 向いているもの 理由
RHEL・Fedora・AlmaLinux 等のサーバー Podman OS のリポジトリに入っている。systemd と Quadlet で運用
root のデーモンを置きたくない Podman デーモンなし・rootless が基本
複数のユーザーが1台を共有 Podman ユーザーごとにイメージ・コンテナが分かれる
Kubernetes へ持っていく前に試す Podman Pod と kube generate・play がある
Docker Desktop が有料になる組織 Podman Desktop も候補 Podman・Podman Desktop は無料
compose を多用する既存の開発環境 どちらも可 Podman は docker-compose を呼べる。挙動差は試して確かめる
Docker 固有の機能(Swarm 等)を使う Docker Podman には Swarm が無い
チームの手順・CI が docker 前提 Docker(段階的に Podman) alias・DOCKER_HOST で移行を試せる
0個Podman の常駐デーモンAPI は使うときだけ起動
65534コンテナの root のホストでの UIDnobody で rootless 実行した例
1.41Docker CLI がつないだ API の版Podman 4.9.3 の互換 API

Podman 5・6で変わったこと(版の違い)

この節では、ネットや本の手順と自分の Podman の版が違うときに、どこが変わったのかが分かります。

版 主な変更(リリースノート)
4.x rootless の既定のネットワークは slirp4netns。Quadlet は 4.4 から
5.0 rootless の既定のネットワークが pasta に。Quadlet の .pod
5.3 pasta でコンテナからホストへの通信の制限を解消(チュートリアル)
6.0 cgroups v1・iptables・CNI・slirp4netns・BoltDB を削除。Intel の Mac・Windows 10 のサポート終了
6.0 volume prune は匿名ボリュームだけ消す(Docker と同じ。前の動きは --all)
6.0 podman commit は既定でコンテナを一時停止。Docker 互換 API は v1.44
6.1 podman volume rename・podman machine restart。kube generate がヘルスチェックを出力

Podman 6 では、cgroups v1 の Linux では動きません。 この記事の 4.9.3 の環境は cgroupVersion: v1 でした。前の世代のディストリビューションや一部のコンテナ環境は cgroups v1 のことがあるので、Podman 6 にするときは podman info の cgroupVersion を先に確かめます。BoltDB を使っていた環境は、6 の初回起動で SQLite への移行が試みられます。

よくある質問

Q. Podmanの読み方は? A. 「ポッドマン」です。Pod Manager の略で、コンテナの Pod を扱う道具という意味です。

Q. PodmanとDockerの違いは? A. いちばん大きな違いは、Podman には常駐するデーモンが無く、一般ユーザーの権限(rootless)で動かすのが基本なことです。ほかに、Pod を作れる、Kubernetes の YAML を出せる、systemd(Quadlet)で自動起動する、という違いがあります。コマンドとイメージはほぼ共通です。

Q. Podmanは無料ですか?商用で使えますか? A. Podman も Podman Desktop も無料のオープンソースです(Podman Desktop は Apache License 2.0)。Docker Desktop のような、会社の規模で有料になる条件はありません。

Q. dockerコマンドはそのまま使えますか? A. 多くは docker を podman に置き換えるだけで動きます。alias docker=podman か podman-docker パッケージで、docker と打っても Podman が動くようにできます。Swarm など Docker 固有の機能はありません。

Q. docker-compose(compose.yaml)は使えますか? A. podman compose で使えます。podman compose は docker-compose か podman-compose を呼び出す仕組みで、どちらかを入れておきます。2サービスの compose.yaml を動かした例は compose の節にあります。

Q. Podman Desktopとは? A. Podman を画面で操作するアプリで、Windows・Mac・Linux で使えます。初回の案内で Podman・仮想マシン・compose・kubectl を入れられます。最新は 1.30.5 です(2026年10月22日時点)。

Q. WindowsやMacでPodmanは使えますか? A. 使えます。どちらも Linux の仮想マシンの中で Podman が動き、podman machine init・podman machine start で用意します。Podman 6.0 で Windows 10 と Intel の Mac はサポート対象から外れました。

Q. rootlessとは?rootで動かすのと何が違いますか? A. 一般ユーザーでコンテナを動かし、コンテナの中の root をホストのそのユーザーに対応させる方式です。実行例では、コンテナの root がホストでは UID 65534 の nobody でした。80 番など 1024 未満のポートがそのままでは使えない、subuid・subgid の設定が要る、などの違いがあります。

Q. Docker Hubのイメージは使えますか? A. 使えます。docker.io/library/nginx のように完全な名前で書くと確実です。短い名前(nginx)は registries.conf に検索先が無いとエラーになります。

Q. QuadletとPodman generate systemdの違いは? A. どちらも systemd でコンテナを動かすためのものですが、generate systemd は非推奨になり、実行すると「DEPRECATED command」と表示されます。Quadlet は .container ファイルを置いて systemctl daemon-reload するだけで、.service が自動で作られます。

Q. Docker用のツール(VS Code の Dev Containers など)はPodmanで動きますか? A. Docker の API を使うツールは、podman system service か podman.socket で API を起動し、DOCKER_HOST を Podman のソケットに向けるとつながります。Docker CLI 29.4.3 は API 1.41 で Podman 4.9.3 につながりました。ツールごとの細かい違いは、そのツールのドキュメントで確かめます。

まとめ

  • Podman は、デーモンなしでコンテナを動かす Docker 互換のコンテナエンジン。読み方はポッドマン。
  • rootless が基本で、コンテナの root はホストでは一般ユーザー(実行例では UID 65534)。subuid・subgid の設定と、1024 未満のポートの制限に注意する。
  • コマンドは docker とほぼ同じ。alias docker=podman や、podman system service+DOCKER_HOST で Docker のツールからも使える。
  • Pod でコンテナをまとめると localhost で通信でき、podman kube generate・play で Kubernetes の YAML と行き来できる。
  • compose は podman compose が docker-compose か podman-compose を呼ぶ。自動起動は Quadlet の .container で systemd に任せる。
  • Mac・Windows は podman machine か Podman Desktop。最新は Podman 6.1.4・Podman Desktop 1.30.5(2026年10月22日時点)で、6.0 で cgroups v1・Windows 10・Intel Mac のサポートが終わった。

参考・出典

確認日はいずれも 2026年10月22日です。

  • Podman「Podman Installation Instructions」:https://podman.io/docs/installation
  • Podman Documentation「podman-systemd.unit(Quadlet)」:https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html
  • Podman Documentation「podman-compose」:https://docs.podman.io/en/latest/markdown/podman-compose.1.html
  • containers/podman「Basic Setup and Use of Podman in a Rootless environment」:https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md
  • containers/podman「Podman for Windows」:https://github.com/containers/podman/blob/main/docs/tutorials/podman-for-windows.md
  • containers/podman「RELEASE_NOTES.md」:https://github.com/containers/podman/blob/main/RELEASE_NOTES.md
  • containers/podman「Releases」:https://github.com/containers/podman/releases
  • Podman Desktop「Installing Podman Desktop on Windows」:https://podman-desktop.io/docs/installation/windows-install
  • Podman Desktop「Installing Podman Desktop on macOS」:https://podman-desktop.io/docs/installation/macos-install
  • Podman Desktop「Releases」:https://github.com/podman-desktop/podman-desktop/releases
  • containers/podman-compose「Releases」:https://github.com/containers/podman-compose/releases
  • Red Hat「Podman とは」:https://www.redhat.com/ja/topics/containers/what-is-podman
  • CNCF「Podman Container Tools」:https://www.cncf.io/projects/podman-container-tools/
  • CNCF「Podman Desktop」:https://www.cncf.io/projects/podman-desktop/
  • Docker Docs「Docker Desktop license agreement」:https://docs.docker.com/subscription/desktop-license/

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Podmanとは|Dockerとの違い・使い方とrootless・Quadlet実例」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?