[Tips] PodmanでDockerのコマンドを使う方法

[Tips] PodmanでDockerのコマンドを使う方法

2025.10.23

クラウド事業本部コンサルティング部の石川です。コンテナ技術といえば、デファクトスタンダードの「Docker」であり、dockerコマンドに慣れ親しんでいる開発者は多いはずです。しかし、最近では「Podman」というコンテナエンジンも注目を集めています。Podmanは無料で利用でき、Dockerデーモンを必要としない(デーモンレス)アーキテクチャなどの特徴を持っています。

https://podman.io/features

PodmanのPodmanコマンドはDockerコマンドと高い互換性を持つように設計されており、公式にも「dockerコマンドのほとんどは、podmanに置き換えるだけで動作する」と謳われています。とはいえ、長年のdocker psdocker buildといった慣れ親しんだdockerコマンドを、podmanと打ち替えるのは面倒です。既存のスクリプトやCI/CDパイプラインを修正するのも手間がかかります。

本日は、 Podmanでも dockerコマンドやdocker-composeコマンド が(擬似的に)実行できる方法について紹介します。

前提条件

私の環境は、以下のとおりです。

  • MacBook Air (M4)
  • macOS Sequoia 15.6.1
  • podman version 5.6.0

設定の流れ

  1. podman-compose (サードパーティ製ツール)をインストールする
  2. dockerコマンドを実行すると podmanコマンドが実行するように設定する
  3. docker-composeコマンドを実行すると podman-composeコマンドが実行するように設定する

1. podman-compose (サードパーティ製ツール)をインストールする

Podmanのコアコマンドセットには、docker-compose に直接相当する機能は標準では含まれていません。そのため、docker-compose と同じ docker-compose.yml ファイルをそのまま使いたい場合、 podman-compose というツールをインストールして使用します。

このツールは、docker-compose と同じコマンド(up, down, ps など)を提供し、YAML ファイルを解釈して内部で podman コマンドを実行します。

% pip install podman-compose
Collecting podman-compose
  Downloading podman_compose-1.5.0-py3-none-any.whl.metadata (5.6 kB)
Requirement already satisfied: python-dotenv in /Users/ishikawa.satoru/.pyenv/versions/3.13.7/lib/python3.13/site-packages (from podman-compose) (1.1.1)
Collecting pyyaml (from podman-compose)
  Downloading pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl.metadata (2.4 kB)
Downloading podman_compose-1.5.0-py3-none-any.whl (47 kB)
Downloading pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl (173 kB)
Installing collected packages: pyyaml, podman-compose
Successfully installed podman-compose-1.5.0 pyyaml-6.0.3

補足: Podman Desktopからpodman-composeをインストールすることもできるようです。

2. dockerコマンドを実行すると podmanコマンドが実行するように設定する

podmanコマンドのパスに対して、シンボリックリンクを設定します。

sudo ln -sf $(which podman) /usr/local/bin/docker

動作確認をしてみます。

% docker --version
docker version 5.6.0

dockerじゃないのですが...dockerのように動作してくれます。

3. docker-composeコマンドを実行すると podman-composeコマンドが実行するように設定する

podman-composeコマンドのパスに対して、シンボリックリンクを設定します。

% sudo ln -sf $(which podman-compose) /usr/local/bin/docker-compose

もし、pyenvを使っている場合は、上記のパスではなく実際のバイナリへ直接リンクを設定してください。

% sudo ln -sf $(pyenv which podman-compose) /usr/local/bin/docker-compose

% ls -la /usr/local/bin/docker-compose
lrwxr-xr-x@ 1 root  wheel  64 Oct 22 18:57 /usr/local/bin/docker-compose -> /Users/ishikawa.satoru/.pyenv/versions/3.13.7/bin/podman-compose

動作確認をしてみます。

% docker-compose --version                                
podman-compose version 1.5.0
podman version 5.6.0

動作確認

Docker公式のawesome-composeからflask-redisを利用して、dockerコマンドとdocker-composeコマンドの動作確認します。

% git clone https://github.com/docker/awesome-compose.git  && cd awesome-compose/flask-redis
Cloning into 'awesome-compose'...
remote: Enumerating objects: 2781, done.
remote: Counting objects: 100% (16/16), done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 2781 (delta 6), reused 1 (delta 1), pack-reused 2765 (from 2)
Receiving objects: 100% (2781/2781), 8.51 MiB | 16.47 MiB/s, done.
Resolving deltas: 100% (1344/1344), done.
ishikawa.satoru@HL01851 flask-redis % tree
.
├── app.py
├── compose.yaml
├── Dockerfile
├── README.md
└── requirements.txt

1 directory, 5 files

docker-compose up -d

% docker-compose up -d
STEP 1/7: FROM --platform=linux/arm64 python:3.10-alpine AS builder
Resolved "python" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull docker.io/library/python:3.10-alpine...
Getting image source signatures
Copying blob sha256:1ec6c3ed91d8b004b1c3416b006bf0f6d3299171b57b2ef58cdd20dc7581734a
Copying blob sha256:6b59a28fa20117e6048ad0616b8d8c901877ef15ff4c7f18db04e4f01f43bc39
Copying blob sha256:5767682a7f5ada1bbc82a32ed7452f6ace6f5aabfc82ec197c2fcfd2238dc525
:
:
:
Copying blob sha256:0e6204cd32aba70b1f9784722646aae4c7c858645f74a9228012526166718fcc
Copying config sha256:88923bcac4adbf325ce6b4a1c9fc91daf2438950f4186242bbf4dfc43cef3dd2
Writing manifest to image destination
WARNING: image platform (linux/amd64) does not match the expected platform (linux/arm64)
c49be59336549cf517a0df3a3d42d8acd4b4c605f13b8c3dea936c3cc1779305
14e3bd8469419bae5d70dc55c045f0d269c9ff3fb5170575544c9ee4e529a9bd
flask-redis_redis_1
flask-redis_web_1

docker-compose ps

% docker-compose ps
CONTAINER ID  IMAGE                                COMMAND               CREATED             STATUS             PORTS                   NAMES
c49be5933654  docker.io/redislabs/redismod:latest  --loadmodule /usr...  About a minute ago  Up About a minute  0.0.0.0:6379->6379/tcp  flask-redis_redis_1
14e3bd846941  localhost/flask-redis_web:latest     app.py                About a minute ago  Up About a minute  0.0.0.0:8000->8000/tcp  flask-redis_web_1

docker-compose down

% docker-compose down
flask-redis_web_1
flask-redis_redis_1
flask-redis_web_1
flask-redis_redis_1
5a10aa29f04456f4425096e32dd049f684cf34ebf509927d0e7a8be9cd9f1eb9
flask-redis_default

docker image ls

% docker image ls
REPOSITORY                    TAG          IMAGE ID      CREATED        SIZE
localhost/flask-redis_web     latest       2a20ea655b57  3 minutes ago  73 MB
docker.io/library/python      3.10-alpine  93d7a310b7d7  13 days ago    58.2 MB
docker.io/redislabs/redismod  latest       88923bcac4ad  3 years ago    1.7 GB

最後に

私が使う用途では、今回ご紹介した方法で困ったことはありませんでした。また、この設定をしても、podmanコマンドは従来通り使えるので、設定による副作用もないはずです。今日現在では、これが最もベター方法ではないかと思います。

一方、Podmanのコマンドへ Dockerのコマンドのシンボリックリンクを設定して、Docker のように振る舞わせる場合、互換性は高いですが、100%同一ではないため、特に複雑なワークフローや特定のツール連携で問題が顕在化します。

補足: aliasを設定する方がシンプルでは?

シンボリックリンクではなく、aliasを設定する方がシンプルでは?と疑問を持つ方もいるかも知れません。実際に aliasを設定する方法を紹介しているブログも多く見られます。しかし、シェルスクリプト(.sh ファイルなど)の内部で docker コマンドを呼び出した場合、デフォルトではエイリアスは展開(実行)されません。また、VSCode のターミナル機能など、ターミナル以外のプログラムが内部的に docker コマンドを呼び出す場合、それらのプログラムはあなたのシェルのエイリアス設定を知りません。

エイリアスが「シェル」レベルの機能であるのに対し、シンボリックリンクは「ファイルシステム(OS)」レベルの機能です。上記のように ln -s /usr/bin/podman /usr/local/bin/docker のようにシンボリックリンクを設定したとします。この場合、sudo を使おうが、シェルスクリプトから呼ばれようが、OSが $PATH(コマンドを探す場所のリスト)の中から docker という名前の実行ファイルを探しに行った結果、podman 本体にたどり着きます。そのため、エイリアスが機能しない上記のようなケースでも、シンボリックリンクであれば意図した通り podman を実行できるのです。この違いを認識して使い分けられるのであれば、aliasを設定するのでも構いません。

この記事をシェアする

FacebookHatena blogX

関連記事