Docker ComposeからPodmanに移行する
環境
-
OS: CentOS Stream 10
-
移行元: Docker + Docker Compose
-
移行元: Podman(ユーザー権限) + Podman Compose
サードパーティーのものがDocker Composeしか提供されていない時に「docker-compose.yml」のままPodmanで動かせないかなと思って試行錯誤。
自作のものはKubernetes YAMLに書き直せばよいものの、配布されているものはいつ変わるかわからないので出来るだけそのまま動かしたかった。
動かす
Podmanのインストール
これはCentOS Stream 10に標準で入っていた。
Podmanの有効化
デーモンレスなのでコマンドをたたけば動くみたいだが、Cockpit上で「Podmanコンテナー」が表示された方が気持ちいい。
systemctl --user enable --now podman.socket
ユーザー権限でpodman.socketサービスを立ち上げれば見られるようになる。
podman-composeのインストール
標準だとpythonは入っているがpipが入っていないので、追加でインストールする。
sudo dnf install python3-pip
その後、podman-composeをインストールする。
pip3 install podman-compose
podman-composeでPodの実行
docker-compose.ymlが保存されているディレクトリ上で
podman-compose up
で普通に立ち上がる(はずだった。)
トラブルシューティング
[.env]の中身が参照されない
うまく動かないので以下のコマンドで認識されたconfigファイルを確認する
podman-compose config
.envに書いた環境変数COMPOSE_FILE
が参照されていない。
podman-composeのソースコードを見たらYAMLの読み込み後に.envを読み込んでいるので、これだと動かない。
-fパラメータを使うか
podman-compose -f docker-compose.yml -f docker-compose.production.yml up
環境変数に入れるしかない。
COMPOSE_FILE=docker-compose.yml:docker-compose.production.yml podman-compose up
.bash_profileに書くか迷ったけど、結局実行用のスクリプトファイルを用意することにした。
う~ん、だったらもうCOMPOSE_FILE
環境変数なんて要らないじゃないか。
PC再起動時に自動起動されない
docker-compose.ymlにはrestart: always
と記載してあるが、再起動しても起動しなかった。
systemctl --user enable podman-restart
podman-restartサービスを有効にすることで、ログイン後に自動起動させることはできたが、OS起動のあとに勝手にコンテナも立ち上がってほしい。
loginctl enable-linger ユーザー名
ログインしていない状態(起動直後やログアウトしているとき)でもユーザー権限のサービスを動作させるよう、systemdにユーザー名を登録する。
これでコンテナを自動起動させようとすることはできたが、podman-restartが以下のエラーで停止している。
pasta[1364]: External interface not usable
podman[1280]: Error: unable to start container "(コンテナID)" setting up Pasta: pasta failed with exit code 1:
podman[1280]: External interface not usable
systemd[1047]: podman-restart.service: Main process exited, code=exited, status=125/n/a
systemd[1047]: podman-restart.service: Failed with result 'exit-code'.
pastaってなんだろうなと思ったら、Podmanが依存するネットワーク関係のパッケージの模様。
ネットワーク機能が利用できる前に立ち上がるためエラーが起きているようだ。
通常であればnetwork.target
を待機するように記述すればよいのだが(というかすでにpodman-restart.service
へ書いてある)、ユーザーユニットはシステムユニットを待機できない模様。
なんだそれやる気あんのか。
ということで
podman-restart.service
を編集しない- docker-compose.ymlを維持してそのまま流用(ユニットファイルを作らない)
- コンピューターの起動に合わせてコンテナを自動起動
- Podmanをユーザー権限で動かす
という条件を満たす方法は2025年1月時点ではないようです。動いていたDockerの環境返してくれ
なので苦渋の決断として podman-restart.service
ファイルを編集して待機先を変えてあげることにした。
先ほどのリンク(GitHubのIssue)に出てきているような回避策はすでに
/usr/lib/systemd/user/podman-user-wait-network-online.service
へインストールされていたので、それを待つよう変えるだけで良い。
/usr/lib/systemd/user/podman-restart.service
の中身を以下へ。
[Unit]
Description=Podman Start All Containers With Restart Policy Set To Always
Documentation=man:podman-start(1)
StartLimitIntervalSec=0
Wants=podman-user-wait-network-online.service
After=podman-user-wait-network-online.service
変えてあるのはWants
とAfter
のところ。
この状態でOSを再起動したらちゃんとコンテナが立ち上がってくれた。
う~ん、忘れたころにこのファイルがもとに戻っていて動かなくなりそう。
試してないけどpodman-composeにこだわらなければ以下の手段で回避できそう。
podman generate systemd ~
で作ったユニットファイルまたはQuadletに読み込ませるユニットファイルに
After=podman-user-wait-network-online.service
Wants=podman-user-wait-network-online.service
を記載してあげれば動きそう。誰か公式のドキュメントに書いてくれていてもいいじゃない。
終わりに
podman-composeを頼りにするくらいなら、公式ドキュメントも整備されているしDockerのほうが無難な気がする。
今回の出鼻をくじかれた経験から思うに
docker-compose.ymlがそのまま使えるし互換性がある
とはいかない。
Discussion