![[Tips] PodmanでDockerのコマンドを使う方法](https://images.ctfassets.net/ct0aopd36mqt/wp-thumbnail-6f0a5efa228cc0991082d0676ae1d12d/47d32302c5a9eb394ad2e4d4c5a42a32/Podman-1.png?w=3840&fm=webp)
[Tips] PodmanでDockerのコマンドを使う方法
クラウド事業本部コンサルティング部の石川です。コンテナ技術といえば、デファクトスタンダードの「Docker」であり、docker
コマンドに慣れ親しんでいる開発者は多いはずです。しかし、最近では「Podman」というコンテナエンジンも注目を集めています。Podmanは無料で利用でき、Dockerデーモンを必要としない(デーモンレス)アーキテクチャなどの特徴を持っています。
PodmanのPodmanコマンドはDockerコマンドと高い互換性を持つように設計されており、公式にも「dockerコマンドのほとんどは、podmanに置き換えるだけで動作する」と謳われています。とはいえ、長年のdocker ps
やdocker build
といった慣れ親しんだdocker
コマンドを、podman
と打ち替えるのは面倒です。既存のスクリプトやCI/CDパイプラインを修正するのも手間がかかります。
本日は、 Podmanでも docker
コマンドやdocker-compose
コマンド が(擬似的に)実行できる方法について紹介します。
前提条件
私の環境は、以下のとおりです。
- MacBook Air (M4)
- macOS Sequoia 15.6.1
- podman version 5.6.0
設定の流れ
podman-compose
(サードパーティ製ツール)をインストールするdocker
コマンドを実行するとpodman
コマンドが実行するように設定する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
を設定するのでも構いません。