podman cpでコピーしたファイルの所有者がrootに変わった。podman psを打っても作ったはずのコンテナが出てこない。Podmanはコマンド名こそDockerとほぼ同じですが、既定値や6.0で変わった挙動でつまずく箇所があります。この記事では、Fedora 45コンテナ内のPodman 6.1.3(rootful)で2026年10月13日に実行したコマンドと出力をもとに、イメージ・コンテナ・ファイルコピー・書き出し・ネットワークの主要コマンドを用途別にまとめました。目的のコマンドは下の早見表から探してください。
まとめ:用途別Podmanコマンド早見表
Podmanの公式マニュアルはpodman(1)で「alias docker=podman」と書くほどDocker互換のCLIで、ほとんどのコマンドはdockerをpodmanに置き換えれば通ります。デーモンを持たない設計の違いはPodmanとdockerの違いは?デーモンレス・rootlessの仕組みと移行判断で解説しています。
| やりたいこと | コマンド例 |
|---|---|
| イメージを取得 | podman pull docker.io/library/alpine:3.22 |
| イメージ一覧 | podman images |
| コンテナを作って起動 | podman run -d --name web docker.io/library/alpine:3.22 sleep 600 |
| 停止中のコンテナを起動 | podman start web |
| 実行中のコンテナ一覧 | podman ps |
| 停止中も含めた一覧 | podman ps -a |
| コンテナに入る | podman exec -it web sh |
| ホストからコンテナへコピー | podman cp ./a.txt web:/root/ |
| コンテナからホストへコピー | podman cp web:/etc/os-release . |
| 停止・削除 | podman stop web / podman rm web |
| コンテナをイメージ化 | podman commit web myimg:v1 |
| イメージをファイルに保存 | podman save -o img.tar myimg:v1 |
| ネットワーク一覧 | podman network ls |
| 環境の確認 | podman version / podman info |
迷いやすい点は3つです。
podman cpは--archiveが既定でtrueのため、コンテナへコピーしたファイルの所有者はコンテナの主UID/GID(多くはroot)になります。元の所有者を残すなら--archive=falseです。podman psは実行中だけを表示し、rootと一般ユーザーではコンテナの保存先そのものが別です。- Podman 6.0から
podman volume pruneは名前付きボリュームを消さなくなり、podman commitは既定でコンテナを一時停止します。
Podmanのバージョンと6.0で変わったコマンド
podman version・podman infoによる環境確認
Podmanは2026年10月時点で6.1系と5.8系の2本が並行して更新されています。GitHubのリリース一覧では、2026年10月12日にv6.1.4とv5.8.9が同日に公開されました。リポジトリは6.0でCNCF管理の組織へ移り、URLはgithub.com/podman-container-tools/podmanになっています。手元の版はディストリビューションで決まり、Fedora 45は6.1.3、Fedora 44は5.8系です。
$ podman version
Client: Podman Engine
Version: 6.1.3
API Version: 6.1.3
$ podman info --format '{{.Host.NetworkBackend}} {{.Host.CgroupsVersion}} {{.Store.GraphDriverName}} db={{.Host.DatabaseBackend}}'
netavark v2 overlay db=sqlite
podman infoの--formatで必要な項目だけ取り出せます。上の出力は、ネットワークがnetavark、cgroupsがv2、ストレージドライバがoverlay、内部DBがSQLiteという6系の標準構成です。各コマンドの詳しいオプションはpodman cp --helpかman podman-cpで引けます。
Podman 6.0の破壊的変更のうちコマンドに効くもの
2026年6月24日公開のPodman 6.0.0は、リリースノートのBreaking Changesに次の項目を挙げています。5系の手順書やスクリプトをそのまま流用すると結果が変わるものだけを抜き出しました。
| 対象 | 5系まで | 6.0以降 |
|---|---|---|
podman volume prune |
未使用の全ボリューム | 匿名ボリュームのみ(全部は--all) |
podman commit |
一時停止しない | 既定で一時停止(--pause=falseで旧挙動) |
podman volume lsの複数filter |
OR | AND |
| CNIネットワーク | 選択可 | 削除(netavarkのみ) |
| slirp4netns | 選択可 | 削除(pastaのみ) |
| cgroups v1・iptables | 動作 | 非対応(v2・nftablesが必須) |
| Intel Mac・Windows 10 | 対応 | 非対応 |
Intel MacやWindows 10でpodman machineを使っている場合は、5.8系に留まるか、別のランタイムへ移る判断が必要です。Mac向けの代替はColimaとは?MacでDocker Desktopを外す導入手順と設定の落とし穴【0.10系】で比較しています。
イメージの取得・一覧・削除(pull・images・rmi・prune)
イメージはpodman pullで取得します。レジストリ名を省くとregistries.confの検索先から候補を選ぶ確認が出る環境があるため、スクリプトではdocker.io/library/alpine:3.22のように完全な名前で書くのが確実です。
podman pull docker.io/library/alpine:3.22
podman images --format '{{.Repository}}:{{.Tag}}'
podman rmi docker.io/library/alpine:3.22
podman image prune # タグがなく、他のイメージやコンテナから参照されないイメージを削除
podman image prune -a # コンテナが使っていないイメージをすべて削除
コンテナが参照しているイメージはpodman rmiで消せません。6.1.3では次のエラーで止まりました。停止済みのコンテナも参照に数えるので、先にpodman rmで対象コンテナを消します。podman rmi -fを使うと、そのイメージを使っているコンテナも一緒に削除されます(6.1.3でも実行後のpodman ps -aは空になりました)。
Error: image used by 5721dede6c65...: image is in use by a container: consider listing external containers and force-removing image
podman runのオプションとコンテナの起動(run・start)
podman run でよく使うオプション
podman runはイメージから新しいコンテナを作って起動します。podman-run(1)のオプションは100を超えますが、日常的に使うのは次の範囲です。
| オプション | 意味 |
|---|---|
-d |
バックグラウンドで起動 |
-it |
標準入力を開き疑似TTYを割り当てる |
--name web |
コンテナ名を付ける |
--rm |
終了時にコンテナと匿名ボリュームを削除 |
--replace |
同名コンテナがあれば置き換える |
-p 8080:80 |
ホストの8080をコンテナの80へ転送 |
-v $PWD/data:/data:Z |
ホストのディレクトリをマウント(SELinuxラベル付与) |
-e KEY=value |
環境変数を渡す |
--network mynet |
接続するネットワークを指定 |
--userns=keep-id |
rootless時にホストのUIDをコンテナ内でも同じにする |
SELinuxが有効なFedoraやRHELでは、-vにラベル指定が無いとコンテナからマウント先を読めないことがあります。:Zはそのコンテナ専用のラベルを付けるので、同じディレクトリを複数のコンテナで共有するときは:z(小文字)を使います。--rm付きで起動したpodman run --rm --name tmp1 docker.io/library/alpine:3.22 trueは、終了直後のpodman ps -aに何も残りませんでした。
podman run と podman start の違い
podman runは毎回新しいコンテナを作り、podman startは作成済みのコンテナを起動し直します。同じpodman runを--name付きで2回打つと、the container name "web" is already in useのエラー(終了コード125)になり、置き換えるには--replaceを付けるよう案内されます。使い回すコンテナはrunを1回だけにし、以降はstartとstopで扱います。
$ podman run --name once docker.io/library/alpine:3.22 echo hi
hi
$ podman start -a once
hi
podman startは既定では出力を表示しないため、終了済みのコンテナを再実行して結果を見るときは-a(attach)を付けます。podman-start(1)のとおり、作成時の--ttyや--interactiveはstart側で変えられません。TTYが要るなら作り直してください。Docker側の起動コマンドの使い分けはDockerコンテナ起動コマンドの使い分け|run・start・execと起動しない時の対処にまとめています。
コンテナの確認(ps・inspect)
podman ps でコンテナが表示されない原因
podman psは実行中のコンテナだけを出します。終了したonceは-aを付けて初めて見えます。
$ podman ps --format '{{.Names}} {{.Status}}'
web Up 1 second
$ podman ps -a --format '{{.Names}} {{.Status}}'
web Up 1 second
once Exited (0) Less than a second ago
-aでも出ないときは、実行ユーザーを確かめます。podman(1)の--rootの説明によると、保存先の既定はUID 0なら/var/lib/containers/storage、それ以外のユーザーは$HOME/.local/share/containers/storageです。sudo podman runで作ったコンテナは、一般ユーザーのpodman ps -aからは見えません。作ったときと同じユーザーで確認してください。
Buildahなど他のツールが同じストレージに作ったコンテナは、podman-ps(1)の--externalで表示されます。podman rmiが「external containers」を理由に失敗したときに確かめる場所です。Buildahの使い方はBuildahとは?buildah buildの使い方とrootless・Kubernetes内ビルドの設定で扱っています。
podman inspectによる状態・設定の抽出
podman inspectはコンテナやイメージの設定をJSONで出します。全体は長いので、--formatで欲しい値だけ抜くのが実用的です。
$ podman inspect web --format '{{.State.Status}}'
running
$ podman image inspect myimg:v1 --format '{{.Config.Cmd}} layers={{len .RootFS.Layers}}'
[sleep 600] layers=2
podman execによるコンテナ内コマンドの実行
podman exec -itによる対話シェルの起動
podman exec -it web shで、実行中のコンテナにシェルで入れます。-iは標準入力を開いたままにし、-tは疑似TTYを割り当てます。Alpineなどbashを含まないイメージでpodman exec -it web bashを打つと、executable file `bash` not found in $PATHで終了コード127が返ります。その場合はshを使います。
作業ディレクトリ・ユーザー・環境変数と終了コード
-wで作業ディレクトリ、-uで実行ユーザー、-eで環境変数を渡せます。コンテナ内のコマンドの終了コードは、そのままpodman execの終了コードになります。
$ podman exec -w /etc -u nobody -e FOO=bar web sh -c 'pwd; id -un; echo $FOO'
/etc
nobody
bar
$ podman exec web sh -c 'exit 7'; echo $?
7
CIのヘルスチェックでpodman exec web pg_isreadyのように使えば、コンテナ内の判定結果をそのままジョブの成否にできます。
podman execの実行条件と停止中のエラー
podman-exec(1)は対象を「running container」に限っています。停止したコンテナに打つと、6.1.3では次のエラーと終了コード255で返りました。先にpodman start webで起動してから実行します。
Error: can only create exec sessions on running containers: container state improper
停止中のコンテナからファイルを取り出したいだけなら、起動しなくても次のpodman cpで取り出せます。
podman cpによるファイルコピー
この章の実行例は、次の準備をした状態で打っています。
podman run -d --name web docker.io/library/alpine:3.22 sleep 600
podman run -d --name db docker.io/library/alpine:3.22 sleep 600
podman run --name once docker.io/library/alpine:3.22 echo hi # 終了済みのコンテナ
printf 'hello\n' > /tmp/a.txt
mkdir -p /tmp/d/sub && printf '1\n' > /tmp/d/sub/f
podman cpの書式・3つのコピー方向・停止中の利用
書式はpodman cp [オプション] [コンテナ:]コピー元 [コンテナ:]コピー先で、podman container cpも同じコマンドです。podman-cp(1)はホストからコンテナ、コンテナからホストに加えて、コンテナ同士のコピーにも対応し、コンテナは実行中でも停止中でもよいとしています。6.1.3でこの3方向のコピーと、停止中のコンテナへのコピーを確かめました。
# ホスト → コンテナ
podman cp /tmp/a.txt web:/root/
# コンテナ → ホスト
podman cp web:/etc/os-release /tmp/osr
# コンテナ → コンテナ(ホストを経由しない)
podman cp web:/root/a.txt db:/tmp/
# 停止中のコンテナにもコピーできる
podman cp /tmp/a.txt once:/tmp/
# - を指定するとtarストリームで標準出力へ
podman cp web:/root/a.txt - | tar -tvf -
コンテナ間のコピーはpodman cp web:/root/a.txt db:/tmp/の1回で済み、db側でcat /tmp/a.txtするとhelloが返りました。一度ホストへ出して入れ直す2段階の手順は要りません。コンテナ内のパスはコンテナのルート(/)からの相対として解釈されます。
所有者の扱い:–archive は既定でtrue
podman-cp(1)は--archive(-a)を「trueのとき、コンテナへコピーしたファイルの所有者はコンテナの主UID/GIDに変わる。falseならコピー元のUID/GIDを保つ。既定はtrue」と説明しています。所有者を1234:1234にしたファイルで確かめた結果です。
$ chown 1234:1234 /tmp/a.txt
$ podman cp /tmp/a.txt web:/root/b.txt
$ podman exec web ls -ln /root/b.txt
-rw-r--r-- 1 0 0 6 Oct 13 12:29 /root/b.txt
$ podman cp --archive=false /tmp/a.txt web:/root/c.txt
$ podman exec web ls -ln /root/c.txt
-rw-r--r-- 1 1234 1234 6 Oct 13 12:29 /root/c.txt
この例ではコンテナの主UID/GIDが0:0のため、コピー後の所有者も0:0です。一般にはコンテナの主UID/GIDに変更され、アプリが読み書きできるかはアクセス権限も含めて確認します。アプリを非rootユーザーで動かすイメージに設定ファイルを入れたのに権限エラーになるときは、コンテナの主ユーザー(podman inspect web --format '{{.Config.User}}'、空ならroot)を確かめ、コピー後にpodman exec -u 0で所有者変更に必要な権限を持つユーザーとしてchownするか、所有者を合わせたファイルを--archive=falseで入れます。
ディレクトリをコピーするときの末尾の /.
コピー先が既存ディレクトリの場合、コピー元をそのまま指定するとディレクトリごと、末尾に/.を付けると中身だけがコピーされます。
$ podman cp /tmp/d web:/srv/
$ podman exec web find /srv
/srv
/srv/d
/srv/d/sub
/srv/d/sub/f
$ podman cp /tmp/d/. web:/opt/
$ podman exec web find /opt
/opt
/opt/sub
/opt/sub/f
podman cp でできないことと代わりの手段
次の3つは6.1.3で終了コード125のエラーになりました。
| 操作 | エラー |
|---|---|
podman cp 'web:/root/*.log' /tmp/ |
could not be found on container web |
| 存在しない親ディレクトリへのコピー | could not be found on container web |
| 既存ファイルのパスへディレクトリをコピー | destination must be a directory when copying a directory |
ワイルドカードはシェルにもコンテナにも展開されず、文字どおりの*.logというファイルを探しに行きます。podman-cp(1)は代わりに、ホストからコンテナへの複数ファイルはxargsやfindと組み合わせ、コンテナからホストへはpodman mountで得たマウントポイントを普通のcpで扱う方法を挙げています。親ディレクトリが無いときは、先にpodman exec web mkdir -p /nonexist/dirで作ります。
3つ目は、podman-cp(1)のコピー先の振る舞いの表でも「cannot copy a directory to a file」というエラー条件として載っています。--overwriteの説明は「ディレクトリと非ディレクトリを相互に上書きできるようにする」ですが、6.1.3では--overwriteを付けても同じエラーで止まりました。コピー先に同名のファイルがあるときは、podman exec web rm /root/targetで消してからコピーするのが確実です。
コンテナの停止・削除・イメージ化(stop・rm・commit)
podman stopは終了シグナルを送り、既定の10秒(-tで変更)待っても止まらなければ強制終了します。podman stop -t 0 dbで止めたコンテナはExited (137)、つまりSIGKILLで終わった状態としてpodman ps -aに残りました。-tを付けない既定のpodman stopでも、PID 1のsleep 600は終了シグナルに反応せず、10秒後に同じ137で終わりました。シグナルを処理しないプロセスをPID 1にすると、停止のたびに10秒待つことになります。
実行中のコンテナはpodman rmで消せず、running or paused containers cannot be removed without forceで止まります。podman rm -f webで停止と削除を一度に行えます。全コンテナを片付けるならpodman rm -f -aです。
podman commit web myimg:v1はコンテナの現在の状態から新しいイメージを作ります。6.0から既定でコンテナを一時停止してから書き出すようになり、6.1.3の--helpにもPause container during commit (default true)と出ます。本番で動いているコンテナをcommitすると、その間リクエストが止まります。止めたくなければ--pause=falseを付けますが、書き込み途中のファイルが不完全な状態で入るおそれがあります。継続的に使うイメージは、commitで作らずにContainerfileからビルドする方が再現できます。
イメージとコンテナのファイル書き出し(save・load・export・import)
ファイルへの書き出しは2系統あり、取り違えると読み込めません。podman-save(1)は親レイヤーを含めてイメージを保存しpodman loadで戻します。podman-export(1)はコンテナのファイルシステムを1枚に平坦化したtarを書き出しpodman importで戻します。同じコンテナから両方を作って読み込み直した結果です。
| 項目 | save → load | export → import |
|---|---|---|
| 対象 | イメージ | コンテナ |
| tarのサイズ | 8,606,720バイト | 8,592,384バイト |
| 読み込み後のCMD | [sleep 600] |
[](空) |
| 読み込み後のレイヤー数 | 2 | 1 |
| タグ | localhost/myimg:v1が戻る |
import時に付け直す |
podman save -o /tmp/img.tar myimg:v1
podman load -i /tmp/img.tar
podman export -o /tmp/fs.tar web
podman import /tmp/fs.tar imported:v1
exportから作ったイメージはCMDが空なので、podman run imported:v1だけでは起動するコマンドがありません。オフライン環境へイメージを運ぶならsave、コンテナ内のファイル一式を調べたり別の場所で展開したりするならexportと使い分けます。
ネットワークとボリュームの管理(network・volume)
podman networkによるネットワークの作成・確認
初期状態のネットワークはpodmanという名前のbridge1つです。podman network createで作ったネットワークには、6.1.3では10.89.0.0/24が割り当てられました。podman-network(1)によると、作成したネットワークは--disable-dnsを付けない限りDNSが有効で、参加したコンテナをコンテナ名で引けます。6.1.3でもmynet上の別コンテナからping appが10.89.0.2に解決されました。
$ podman network ls --format '{{.Name}} {{.Driver}}'
podman bridge
$ podman network create mynet
$ podman network inspect mynet --format '{{.Driver}} {{range .Subnets}}{{.Subnet}}{{end}}'
bridge 10.89.0.0/24
$ podman run -d --name app --network mynet docker.io/library/alpine:3.22 sleep 600
$ podman run --rm --network mynet docker.io/library/alpine:3.22 ping -c1 app
PING app (10.89.0.2): 56 data bytes
使っていないネットワークはpodman network rm mynetかpodman network pruneで消します。コンテナが接続しているネットワークは"mynet" has associated containers with itで削除を拒否されるため、先にそのコンテナを削除するか、-fでコンテナごと消します。
podman volume pruneの6.0以降の既定対象
podman-volume-prune(1)は既定で匿名(名前の無い)未使用ボリュームだけを消すと明記しています。6.1.3でpodman volume create named1のあとpodman volume prune -fを実行しても、named1は残りました。名前付きも含めて消すなら--all、消える対象を先に見るなら--dry-runです。5系のつもりで定期清掃のスクリプトを書いていた場合、6系に上げると名前付きボリュームが溜まり続けます。
Podmanで実際のアプリを動かす例として、DifyをPodmanのrootlessで動かす手順とNotion連携の設定ではrootless特有の権限とSELinuxの設定を扱っています。本番のコンテナ基盤をクラウド上に組む段階では、AWS・Google Cloud・Azureのインフラ構築支援で構成設計から相談できます。
よくある質問
podman ps でコンテナが表示されないのはなぜですか?
podman psは実行中のコンテナだけを表示するので、停止中も見るにはpodman ps -aを使います。それでも出ない場合は実行ユーザーの違いを疑います。rootのコンテナは/var/lib/containers/storage、一般ユーザーのコンテナは$HOME/.local/share/containers/storageに保存され、互いに見えません。sudoで作ったコンテナはsudo podman ps -aで確認します。
podman cp はコンテナが停止していても使えますか?
使えます。公式マニュアルはコンテナが実行中でも停止中でもよいとしており、Podman 6.1.3で停止済みのコンテナへのコピーも成功しました。podman execは実行中のコンテナにしか使えないので、停止中のコンテナからファイルを取り出すときはpodman cpを使います。
podman cp でコンテナからコンテナへ直接コピーできますか?
できます。podman cp web:/root/a.txt db:/tmp/のように両方にコンテナ名を付けると、ホストを経由せずに1回でコピーされます。ワイルドカードは使えないため、複数ファイルはディレクトリ単位でコピーします。
podman run と podman start の違いは何ですか?
podman runはイメージから新しいコンテナを作って起動し、podman startは作成済みのコンテナを起動し直します。runを繰り返すとコンテナが増えるか名前の重複でエラーになるので、使い回すコンテナは--nameを付けて1回だけrunし、以降はstartとstopで扱います。
podman save と podman export はどちらを使うべきですか?
イメージを別の環境へ運ぶならpodman saveとpodman loadです。podman exportはコンテナのファイルシステムを1レイヤーに平坦化し、CMDなどの設定を持たないため、podman importしたイメージはそのままでは起動コマンドがありません。