世界を動かす技術を、日本語で。

DockerをやめてPodmanに乗り換えました(あなたもそうすべきです)

概要

  • VagrantやDockerの登場で開発環境の統一が進み、Dockerは業界標準に
  • セキュリティ脆弱性やリソース消費問題がDocker運用で顕在化
  • Podmanはデーモンレス設計で、より安全かつ軽量なコンテナ運用を実現
  • systemd連携やKubernetes互換など、現代的な運用管理をサポート
  • DockerからPodmanへの移行はほぼシームレスで、実際の移行手順も簡単

DockerからPodmanへの進化とその理由

  • Vagrant 登場時、全ての開発環境を統一する理想郷への期待
  • Docker によるアプリ開発・デプロイ手法の根本的変革
  • 環境の再現性・分離性の高さから「 Just Dockerize it」が常套句に
  • しかし、 dockerdデーモン の常時稼働によるリソース消費・root権限問題
  • 過去の 重大な脆弱性(CVE) や攻撃事例(例:runCエスケープ、Dirty Pipe、API悪用による仮想通貨採掘)
  • 現状維持バイアス」を疑い、より良い選択肢を模索

Podmanの本質的な強み

  • デーモンレス設計 :バックグラウンドで常駐プロセス不要、各コンテナは直接ユーザーの子プロセスとして起動
  • rootless運用 :コンテナ内でroot昇格してもホストでは一般ユーザー権限のまま
  • 単一障害点の排除 :dockerdのクラッシュで全コンテナ停止→Podmanは個別管理
  • リソース消費の最小化 :常駐デーモンが無いため、メモリ・CPU負荷が低減
  • systemd連携podman generate systemdでsystemdユニット自動生成、Linuxサービス管理と完全統合
  • Kubernetes親和性 :Podmanのpod概念はK8sと直結、podman generate kubeでYAML自動生成
  • Unix哲学重視 :ビルドはBuildah、イメージ操作はSkopeoなど、役割分担が明確

DockerからPodman移行の実際

  • Podmanは Docker互換CLI を提供、alias docker=podmanでそのまま置き換え可能
  • Dockerfile等の資産も 修正不要 で利用可能
  • rootlessモード では1024番未満のポートバインド不可(セキュリティ向上のため)
  • Docker socket前提ツールも、PodmanのDocker互換APIで対応可能
  • Docker Composeの複雑なワークフローは、Kubernetes YAMLへの変換が推奨
  • 開発~本番で同じ構成を維持できるメリット

Podman運用の現場での実感

  • セキュリティ管理が 大幅に簡素化、rootlessの恩恵
  • システム監視も リソース利用が安定化
  • Dockerは依然として主流だが、新規プロジェクトや技術選定の自由度があれば Podmanが最適解
  • Linux運用・Kubernetes時代に即した 次世代コンテナ技術

FastAPIアプリをDockerからPodmanへ移行する手順

  • 前提

    • 既存FastAPIプロジェクト(Dockerfile, requirements.txt)
    • Podmanインストール済み(Ubuntu/Debian: sudo apt install podman / Fedora: sudo dnf install podman / macOS: Podman Desktop)
  • Step 1: Dockerfileはそのまま利用可能

    • OCIフォーマット互換
    • 例:
      FROM python:3.10-slim-buster
      WORKDIR /app
      COPY requirements.txt .
      RUN pip install --no-cache-dir --upgrade -r requirements.txt
      COPY . .
      EXPOSE 8000
      CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
      
  • Step 2: イメージビルド

    • podman build -t my-fastapi-app:latest .
    • alias docker=podmanで既存コマンドもそのまま利用可能
  • Step 3: コンテナ実行

    • 開発・テスト用: podman run --rm -p 8000:8000 --name my-fastapi-container my-fastapi-app:latest
    • バックグラウンド実行: podman run -d -p 8000:8000 --name my-fastapi-container my-fastapi-app:latest
    • rootlessモードのため、1024番未満のポートはバインド不可(本番ではリバースプロキシ推奨)
  • Step 4: systemdによる本番運用

    • コンテナ起動 podman run -d -p 8000:8000 --name my-fastapi-container my-fastapi-app:latest
    • systemdサービスファイル生成
      mkdir -p ~/.config/systemd/user/
      podman generate systemd --name my-fastapi-container > ~/.config/systemd/user/my-fastapi-container.service
      
    • サービス有効化・起動
      systemctl --user daemon-reload
      systemctl --user enable my-fastapi-container.service
      systemctl --user start my-fastapi-container.service
      
    • サーバー常駐運用はloginctl enable-linger $(whoami)
  • Step 5: Podによるマルチサービス構成

    • FastAPI+DB等の複数サービスもPodmanのpod機能で簡潔に管理可能

まとめ

  • DockerからPodmanへの移行は 驚くほど簡単 で、セキュリティ・運用面でのメリットが大きい
  • Podmanは Linux時代の標準的なコンテナ運用 を実現
  • 新規開発やインフラ刷新時にはPodmanの採用を強く推奨

Hackerたちの意見

記事の「podman generate systemd」コマンドは廃止予定だよ。代わりにPodman Quadletsがあって、これは(docker-)compose.yamlに似てるけど、systemdユニットファイルで定義されてるんだ。

実際、オーケストレーションや構成をsystemdに任せるのは理にかなってるよね。もうクライアントサーバーのAPI呼び出し(Dockerみたいに)じゃなくて、実際のユーザーランドプロセスだから。

ドキュメントがほとんどないけどね。

Podmanが大好きなんだけど、他の人も言ってるように、すべてのコンテナでうまく動くわけじゃないんだよね。よくPodmanで何かを動かそうとすると、変なエラーが出て、結局Dockerに戻っちゃうことが多い。特にGitLabみたいな大きなコンテナだと、Dockerの履歴やクセに依存してるから、うまくいかないことが多いんだ。自分で何かをビルドする時は、大体Podmanで動かせるんだけど、ランダムなコンテナが動かない状況が続くと、Incusの下でVMを立ち上げて、厄介なコンテナをその中で動かすことになっちゃう。最適ではないけど、精神的には楽になるんだよね。今はIncusがDockerコンテナを動かせるようになったから、Podmanを代わりに使えるか気になるな。両方同時に動かせたら、魔法のようで、いろんな問題が解決できそう。PodmanとDockerのコマンドでGPUアクセスに一貫性がないのはイライラするけど、全体的にはPodmanの方が好きだし、この記事は読む価値があると思う。Rootlessは大きなポイントだね。

Podmanが大好きなんだけど、他の人が言ってるように、すべてのコンテナでうまくいくわけじゃないんだよね。これがブログ記事の一つの理由かもしれない。ユーザーの大半がPodmanを使うようになれば、リリース前にチェックされるようになるんじゃないかな。

変だな、うちはGitLabサーバーとランナーを全部Podmanで動かしてるよ。正直、ランナーをk8sに移行したいと思ってる。でも、今のところうまく動いてる。Traefikを使ってるよ。

他の人たちが問題を言ってる中で、1つ反対意見を言わせて。Podman最高だよ!Dockerは使いにくくて落とし穴だらけだし、Podmanもそんなに悪くない。プラス面として、働いてる会社はライセンスの心配をしなくていいんだ。ウィンウィンだね!

君の会社はライセンスの心配をする必要はないよ。Docker ENGINEは無料でオープンソースだし、Docker DESKTOPは会社で使うにはライセンスを購入する必要があるソフトウェアスイートだ。でも、Linux、Mac、WindowsでWSL2を通じて動くコアコンポーネントのDocker Engineは、完全に1000%無料で使えるんだ。

プラス面として、働いてる会社はライセンスの心配をしなくていいんだ。ウィンウィンだね!これはどの会社にとっても決定的な問題だったの?Docker Desktopの有料ライセンスの要件はかなり合理的だと思う。250人未満の従業員で、年間収益が1000万ドル未満なら無料だし。もし開発チームが10人いて、ライセンスが必要なほど利益が出てるなら、ライセンス代は1人あたり年間9ドルになる。だから、全員で90ドル/年だけど、アメリカの開発者がいるなら、全体の給与はおそらく1人あたり20万ドル以上、つまり約200万ドルになるだろう。その文脈で見ると、90ドルなんてほとんど何でもないよ。開発チームのランチ1回でそれ以上かかることもあるし。私にとってはお得だと思う。すべてのOSで「そのまま動く」公式サポートのツールが手に入るんだから。

「もしDocker Composeのワークフローが複雑すぎるなら、Kubernetes YAMLに変換しちゃえばいいよ。最近はみんなKubernetesを使ってるから、これにこだわる必要ある?」 KubernetesのYAMLはDocker Composeよりもずっと複雑だと思うし、実際、みんながKubernetesを使ってるわけじゃないよ。

LLMを使ってdocker composeからk8s yamlへの翻訳レイヤーを作るのはすごくうまくいくよ。別の話だけど、Podmanはk8s yamlを生成してくれるから、便利で移行が簡単だね。

コンポーズファイルの作り方はわからないけど、k8s yamlの作り方は知ってる。だから、コンポーズは私にとって「複雑」なんだ。

一つの課題は、マルチUIDコンテナを単一のホストユーザーにマッピングすることなんだ。デフォルトでは、コンテナ内のrootがホストでPodmanコンテナを実行しているユーザーにマッピングされる。年々、アプリケーションは非rootユーザーでコンテナを実行するパターンを採用してきた。例えば、www-data、つまりUID 33(Debian)や1000とかね。これらはもはやホストの自分のユーザーにマッピングされず、従属IDになる。すべてのコンテナUIDを単一のホストユーザーにマッピングする簡単な方法があればいいのに。uidmapやusernsオプションはうまくいかなかった(crunがそれらのコンテナを実行できなかった)。従属IDにマッピングするユースケースが見えないんだ。ボリュームマッピングで使うと、ホスト上でそのファイルが孤立して、誰のものでもなくなっちゃう?

もし私の理解が正しければ、これはLinuxのネームスペースの制限だから、DockerやPodmanのようなツールはLinuxのサポートなしにはそのマッピングをサポートできないんだ。でも、UIDを1:1でマッピングする必要があるのは根本的な問題だと思う。そうじゃないと、例えばコンテナ内のユーザー1000と0がホストのユーザー1000にマッピングされちゃう。じゃあ、ホスト上でユーザー1000が所有しているファイルのオーナーは、コンテナ内で誰として表示されるの?

これだね。そして、コンテナ内でも「自分」でいられる方法があればいいな。そうすれば、ログには「あなた」って表示される。

idmapped mountsは見たことある?全てを解決するわけじゃないと思うけど(ファイルシステムの再マッピングだけで、ユーザー権限のカーネル呼び出しには対応してないから)。

ignore_chown_errorsを使うと、他のマッピングなしでrootを自分のユーザーIDにマッピングできるよ。

私はPodmanのユーザーでファンだけど、systemd統合について知っておくべきことが一つあるよ。systemdでUser=fooを設定すれば、シームレスなルートレスコンテナが使えると思うかもしれないけど、実はシームレスな解決策がない難しい問題なんだ。代わりに、86件のコメントが続いているこのディスカッションスレッドを探して、いくつかの人にうまくいった解決策を見つける必要があるよ。 https://github.com/containers/podman/discussions/20573#discu...

Fedoraでpodmanを使った楽しい経験からいくつかリンクを保存してるよ(それにselinuxもね)。確か、Fedoraがcgroups v2を搭載してたからpodmanを使おうと思ったんだけど、Dockerとは相性が悪かったんだよね(自分の無知で、主要な開発ツールとの連携が重要だと思ってたけど、ディストリビューションはしばしば別の考えを持ってる)。 - https://www.redhat.com/en/blog/user-namespaces-selinux-rootl... - https://www.redhat.com/en/blog/sudo-rootless-podman これらの投稿は「クレイジーな問題を解決する方法をとても丁寧に説明している」ってまとめられるかな。

FedoraはPodmanをかなり推してるよね。Fedora Server用のCockpitコントロールパネルがあって、CockpitのDockerプラグインがちゃんと動いてたのに「Podman統合プラグインを使え」って理由で使えなくなったんだ。

まだx86のMacを使ってるよ。Docker Desktopのライセンスが変わったときにPodmanに切り替えようとしたけど、ひどい目に遭った。Podmanは新しいもので、完璧な代替だって言ってるブログがたくさんあったけど、私には合わなかったし、要求もすごくシンプルなのに。結局、Rancher Desktopを使うことにしたけど、これも不安定だったけど、マシだった。1年後、Rancherはかなり良くなってたけど、Podmanは相変わらずMacで安定して動かなかった。さらに1年くらい経ってcolimaに切り替えたんだ。最後にpodmanを試したのは約1年前で、古いMacではまだ問題があった。今のところcolimaは私のニーズには十分だけど、少なくとも2回はbrew updateでcolimaが壊れて、最初から再インストールしなきゃいけなかった。

以前はdocker専用で動いてたツールがあって、podmanのサポートは時間がかかると思ってしばらく放置してたんだけど、実際には調整なしでそのまま動いたんだ。ほぼ摩擦なしで使えるよ。[1] 参考ツール: https://github.com/data-catering/insta-infra

同じく。Podman Desktopは素晴らしい。podman/buildahとそのエコシステムはサーバーでもずっと信頼性が高いよ。