はじめに

こんにちは。インシュアランスサービス部の土居です。
私はアプリ開発に取り組むなかで、Podmanというコンテナを管理できるオープンソースを使っていました。
具体的にはデータベースの構築に活用しており、そのなかでPodmanならではのメリットを感じることがありました。それを踏まえて、コンテナ全般やPodmanに関心のある方に向けてその使い方や工夫した点をご紹介します。

コンテナ

コンテナとは、アプリとその実行に必要なものをまとめてパッケージ化する技術のことで、
動作している環境に挙動が左右されず、また軽量であるため短時間で起動できるなどのメリットがあります。
開発業務では、ローカルでのアプリの動作確認や、CI/CDパイプラインでのユニットテストの実行のためにすぐにデータベースを立ち上げられる点で役立っていました。

Podmanを採用した理由

コンテナを扱うツールにはDockerが挙げられますが、そのGUI(グラフィカル・ユーザー・インターフェース)ツールであるDocker Desktopは特定の条件を満たす組織は利用者ごとに有料のサブスクリプション契約をする必要がある(2025年9月時点)ため、費用面に注意が必要です。Dockerのみであれば無料で利用できますが、GUIなしでは簡単かつ柔軟なコンテナの管理が難しくなる懸念があるため採用しませんでした。
一方、PodmanおよびPodman Desktopはともに無料(2025年9月時点)で扱えます。
また、PodmanのCLI(コマンドライン・インタフェース)はDocker CLIと似ているためDockerを知る人は導入しやすく、必要があればエイリアス(aliasコマンド)によってPodman CLIとDocker CLIを使い分けられます。
さらに、GUIツールであるPodman Desktopは軽量で操作性が優れているため、CLIと併せて簡単かつ柔軟にコンテナを管理できる点が、他のRancher Desktopといったツールと比べて優れていると感じました。
他にもデーモンレスやルートレスといった特徴もありますが、
私は上述の通り、CLIとGUIの使い分けのしやすさ、GUIの操作性の良さが他のツールと比べて優れている点がPodmanのメリットと判断し、採用することとしました。

前提

  • コンテナにデータベースを構築することを例に説明します
  • 記載している環境変数やその値、コマンドはあくまで参考までとしてください
  • Podmanのインストール手順の説明は省略します
  • 紹介内容は以下環境に基づきます
    • データベース:MySQL(コンテナ上で動作)
    • DevOps:Azure DevOps
    • コンテナ管理ツール:
      • CLI:Podman v4.6.2
      • GUI:Podman Desktop v1.19.2

ファイル一覧

コンテナを作成・起動するために用意したファイルは以下の通りです。詳細は後述します。
リポジトリ フォルダ ファイル 内容
example-api なし

(ルートディレクトリ直下)

azure-pipeline.yml CI/CDパイプライン実行時の処理内容の定義
example-tools


script/ut/podman/mysql

run_on_pipeline.sh CI/CDパイプラインでpodmanコマンドをdockerコマンドに読み替えて、run.shを呼び出し
run.sh podmanコマンドでコンテナを起動
docker-compose.yml コンテナ(およびコンテナ起動時の処理)の定義
Dockerfile イメージを作成するための設定
.env 環境変数の定義(MySQL専用)
script/ut/podman podman_common.env 環境変数の定義(全サービス共通)
フォルダ構成は、導入の際にプロジェクトの特性に合わせて検討してください。
当プロジェクトでは用途と扱うサービスの単位でフォルダを分割し、ファイルを配置していました。

GUIを使ったコンテナの作成・起動方法

GUIツールであるPodman Desktopでは、Dockerfileをもとにコンテナを作成できます。
コンテナの検証をしたり、とにかくすぐにコンテナを作成したい時には、この方法が有用でした。
Dockerfileはコンテナの元となるイメージを作成するための情報が記載されたファイルであり、
ここでは「FROM」で元となるイメージ(ここではMySQL)を指定し、「ADD」でMySQLの設定ファイルを追加、「RUN」のあとに続くコマンドでファイルに対する権限を付与しています。これにより、使用するデータベースのイメージの情報と、データベースの設定情報を定義することができます。
※my.cnfはMySQLの設定ファイルです。ここでは詳しい説明は省略します。
FROM mysql:8.0
ADD ./db/mysql_conf/my.cnf /etc/my.cnf
RUN chmod 644 /etc/my.cnf
以下、イメージおよびコンテナを作成する流れを説明します。
※バージョンによって見た目が異なることがあります。
まず、コンテナの画面から「Create」をクリックし、表示されたダイアログから、「Containerfile or Dockerfile」をクリックします。
図1:Podman Desktopの画面(Create A New Container)
次に、Dockerfileのパスなど、必要情報を入力の上、「Build」をクリックします。これでイメージの作成ができます。
図2:Podman Desktopの画面(Build image from Containerfile)
続けて、イメージをもとにコンテナを作成します。
先ほどのダイアログから、今度は「Existing image」をクリックします。
それから、先ほど作成したイメージを選択し、「Run Image」をクリックします。
図3:Podman Desktopの画面(Select an image)
コンテナ名やポート番号、環境変数のパスなど、必要情報を入力の上、「Start Container」をクリックします。
図4:Podman Desktopの画面(Create a container from image docker.io/library/my-custom-image:latest)
これで、コンテナの起動ができました。
起動中は■を押すと停止し、停止中は▶︎を押すと起動します。
プロジェクトではコンテナの作成・起動はCLIでおこない、以降の停止や再起動はGUIでおこなうといったように使い分けていました。
図5:Podman Desktopの画面(Containers)

CLIを使ったコンテナの作成・起動方法

GUIでコンテナを作成できますが、CLIで作成・起動することもできます。
CLIにはコマンドによるコンテナへの細かい設定や処理の実行、複数のコンテナの操作などがやりやすいというメリットがあります。
プロジェクトではdocker-compose.ymlでSQLが格納されているディレクトリを指定することで、コンテナ作成から起動、初期データ投入までを一気に行い、作業効率の向上に役立てていました。

ローカルで実行する場合

以下はrun.sh(コンテナを起動するスクリプト)です。
podmanコマンドを使って必要な処理を行い、コンテナを作成・起動しています。
#!/bin/bash
cd $(dirname $0) 2> /dev/null

# スクリプト名を表示して開始を知らせる
echo start $0

# 各種環境変数を読み込む
. .env
. ../podman_common.env

# 指定されたボリュームが存在しない場合は作成し、存在する場合はその旨を表示
if [[ ! $(podman volume ls -f "name=${VOLUME}" --format '{{.Name}}') == "${VOLUME}" ]]; then
  podman volume create "${VOLUME}" >/dev/null && echo "Created new volume: ${VOLUME}"
else
  echo "Using existing volume: ${VOLUME}"
fi
podman volume ls

# 指定されたネットワークが存在しない場合は作成し、存在する場合はその旨を表示
if [[ ! $(podman network ls -f "name=${NETWORK}" --format '{{.Name}}') == "${NETWORK}" ]]; then
  podman network create "${NETWORK}" >/dev/null && echo "Created new network: ${NETWORK}"
else
  echo "Using existing network: ${NETWORK}"
fi
podman network ls

echo "############ start podman-compose ############"
# 設定ファイルを反映させるため常に再ビルドする。
podman-compose build --no-cache
# コンテナをバックグラウンドで起動
podman-compose up -d
echo "############ end podman-compose ############"

# 実行中のコンテナ一覧をテーブル形式で表示、失敗したらエラーメッセージを表示
echo && podman container ps --format "table {{.ID}}t{{.Image}}t{{.Ports}}t{{.Names}}" || echo "Failed to start container."
以下はdocker-compose.ymlの例です。run.sh内でpodman-compose buildを実行する時に使われます。
version: "3.8"
services:
  # MySQL
  example-db-ut:
    container_name: ${CONTAINER_NAME}
    build: ./
    volumes:
      # 初期データを投入するSQLが格納されているdir
      - ${INIT_SCRIPT}:/docker-entrypoint-initdb.d
      # 永続化するときにマウントするdir
      - ${VOLUME}:/var/lib/mysql
    env_file:
      - .env
    environment:
      - MYSQL_DATABASE=${DB_NAME}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_PASS}
      - MYSQL_ROOT_PASSWORD=${DB_PASS}
      - TZ=${TZ}
      - BIND-ADDRESS=0.0.0.0
    ports:
      - ${DB_PORT}:3306
    networks:
      - ${NETWORK}
networks:
  example-ut-network:
    external: true
volumes:
  example-mysql-ut-data:
    external: true

以下は環境変数が定義されたファイルの例です。上記のファイルで指定されている環境変数の値の参考としてください。

.env(MySQLおよびそのコンテナに関する環境変数)

CONTAINER_NAME=example-db-ut
DB_NAME=example_db_ut
DB_USER=test
DB_PASS=test
DB_PORT=53306
TZ=Asia/Tokyo
VOLUME=example-mysql-ut-data
INIT_SCRIPT=./db/ut/init

podman_common.env(コンテナが属するネットワークに関する環境変数)

export NETWORK=example-ut-network

以上のファイル及び他設定ファイル(my.cnf)を用意のうえ、run.shを実行すればコンテナの作成・起動ができます。

XXXXXXXXXX@XXXXXXXXXXX-XX MINGW64 /c/example-tools
$ script/ut/podman/mysql/run.sh
start script/ut/podman/mysql/run.sh
Using existing volume: example-mysql-ut-data

(中略)

############ end podman-compose ############

CONTAINER ID  IMAGE                                 PORTS                    NAMES
1fc34949e1ab  localhost/mysql_example-db-ut:latest  0.0.0.0:53306->3306/tcp  example-db-ut

CI/CDパイプラインで実行する場合

ここでは例として、Azure Pipelines上で処理が実行されることを前提にazure-pipeline.ymlについて説明します。
azure-pipeline.ymlとはAzure DevOpsの自動化パイプラインの設定ファイルのことで、このファイルをリポジトリに置くことで、Azure Pipelinesがこのファイルを読み込み、記述されたパイプライン(ビルド・テスト・デプロイ等)の処理を自動実行します。
パイプラインの処理のうち、たとえばデータベースを利用するテストが含まれている場合に、リモートでコンテナを作成・起動するケースがあります。
以下はazure-pipeline.ymlの例(一部抜粋)です。scriptでシェルスクリプトファイル(run_on_pipeline.sh)を呼び出し、その中でコンテナを作成・起動するコマンドを実行しています。
resources:
  repositories:
    - repository: example-tools
      type: git
      name: example-tools
      ref: develop
jobs:
  - job: buildAndPublish
    timeoutInMinutes: 120
    pool:
      vmImage: 'ubuntu-latest'
    variables:
      MAVEN_CACHE_FOLDER: $(Pipeline.Workspace)/.m2/repository
      MAVEN_OPTS: '-Dmaven.repo.local=$(MAVEN_CACHE_FOLDER) -Duser.language=ja -Duser.country=JP'
    steps:
      - checkout: self
      - checkout: example-tools
      - task: bash@3
        inputs:
          targetType: 'inline'
          script: |
            chmod -R 755 .
            example-tools/script/ut/podman/mysql/run_on_pipeline.sh
        displayName: 'run docker '
以下、run_on_pipeline.shは、podmanコマンドをdockerコマンドとして読み替えて実行するためのスクリプトファイルです。このファイルをパイプラインで読み込むことで、CI/CDパイプラインではdockerコマンドが、ローカルではpodmanコマンドが実行できます。なお、CI/CDパイプラインでdockerコマンドを用いる理由としては、Azure Pipelines上で動作する仮想マシンに初めからdockerコマンドが用意されているため、インストール不要で利用できることが挙げられます。
#!/bin/bash
cd $(dirname $0)
echo start $0
# 非インタラクティブ時のalias有効化
shopt -s expand_aliases
# podmanをdockerに読み替え
alias podman=docker
# podman-composeをdocker composeに読み替え
alias podman-compose="docker compose"
. run.sh

おわりに

ここまで、Podmanでコンテナを管理する事例をご紹介しました。
操作性の優れたGUIで簡単にコンテナを管理できることや、場面に応じてGUIとCLIを使い分けて柔軟にコンテナを管理できる点でPodmanは優れています。また、他の点においても他のツールに引けを取らないことは、導入を試すなかで感じた点でした。
以上の内容をご参考いただき、Podmanやコンテナを扱う方のお役に立てば幸いです。