- 技術 💻
Podmanとは|Dockerとの違い・使い方とrootless・Quadlet実例
結論
Podmanは、常駐デーモンなしでコンテナを動かす、Docker互換のコンテナエンジンです。一般ユーザー権限(rootless)で動かせ、Pod もまとめて扱えます。
この記事でわかること
- Dockerとの違い8項目と、コマンド対応表30行
- rootless・Pod・compose・Quadletの実行結果
- エラー原文12種と原因・直し方の表
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 との違いを、仕組みと表の両方で確かめられます。
コンテナを作る仕組み
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 です。
WSL を有効にする
PowerShell で wsl --update と wsl --install --no-distribution を実行し、再起動する。
Podman を入れる
GitHub のリリースにある Windows 用インストーラーか、Podman Desktop の初回設定から入れる。
仮想マシンを作る
podman machine init。最小構成の Fedora が入り、Podman 用に設定される。
起動して確かめる
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 usingpodman system connection list, or trypodman machine initandpodman 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 で移行を試せる |
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期連続の黒字決算。