0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Podmanでも使えるDocker Composeとその開発者向けサンプル

Posted at

ほぼ備忘録です。

単一コンテナを単純に動かしたいときにもCompose

ささっとローカルに環境を作りたい場合、コンテナは重宝しますよね。
私はPodman派なのですが、podman runでコンテナを動かすことが多いです。ただ、パラメータを多く配置すると見づらいときもあります。
ビルドされたイメージを利用するだけなら、Composeだと定義内容を把握しやすいという利点があります。

Composeは複数のコンテナを1つのアプリケーションとして動作させることを想定している技術ですが、単一コンテナの場合にも可読性、可搬性というメリットはあります。

ただPodmanだとcomposeをどう使おうか悩むところもあるかと思うので、手順などをまとめておきます。
この記事では、podman desktopおよびpodmanがインストールされた環境を想定しています。動作検証はWindows11で実施しています。

Composeとは

「コンテナは単一機能だけ載せましょう」という共通認識があります。ただ多くのアプリケーションはDBとWebアプリなど複数の機能で構成されるため、コンテナも複数起動する必要があります。常にワンセットで使うコンテナを1つずつ起動するのは面倒なので「ワンセットで管理できるようにしました」という技術です。
コンテナの他、ボリュームやネットワークの定義もまとめることができます。

Dockerから派生して登場したComposeですが、現在はオープンソースとして仕様が管理されています。

定義ファイルをもとに起動する

compose.ymlというファイルでどのように実行するかを管理します。

mariadbコンテナの起動を、runコマンドで起動する場合とcompose.ymlで指定する場合にて比較してみます。

podman run
podman run -d --name my-mariadb -p 3306:3306 -e MARIADB_ROOT_PASSWORD=secret_root_pw -e MARIADB_DATABASE=myapp_db -e MARIADB_USER=app_user -e MARIADB_PASSWORD=app_password -v ./mariadb-data:/var/lib/mysql:Z mariadb:latest
compose.yml
services:
  db:
    image: mariadb:latest
    container_name: my-mariadb
    ports:
      - "3306:3306"
    environment:
      MARIADB_ROOT_PASSWORD: secret_root_pw
      MARIADB_DATABASE: myapp_db
      MARIADB_USER: app_user
      MARIADB_PASSWORD: app_password
    volumes:
      ./mariadb-data:/var/lib/mysql:Z

composeのほうが文字数は多いし、ymlを書いてから実行するという2段階が必要ですが:sweat_smile:、見やすさは圧倒的に上でしょう。細かいミスも減ると思います。
1回だけ実行するのであればrunコマンドでよいですが、隣の人とシェアしたり継続的に使ったりする場合にはcomposeを使うと仕様が伝わりやすいでしょう。

この例は1コンテナだけの指定ですが、複数コンテナを指定できるところがcomposeの本来の使い方です。

実装

Docker向けの「DockerCompose」というプロダクトがcompose仕様のオリジナルとしてリリースされています。これは内部でDockerコマンドを呼び出します。
Podman向けの互換製品として「PodmanCompose」があり、こちらはPodmanコマンドを呼び出します。

Podmanではどちらの実装を使うべきか

DockerComposeがおすすめ

一見するとPodmanComposeのほうが妥当ですが、DockerComposeとの互換性に少し課題もあるようです。
Podmanのオプションで「Dockerコマンドのエイリアスとして使う」という指定が可能なので、この指定を行ったうえでDockerComposeを使うほうが無難であるといえます。

Podman自体にもcomposeというラッパーコマンドがあり、これが呼び出されたらDockerComposeまたはPodmanComposeを呼び出すことになっています。もし端末に両方ともインストールされている場合は、DockerComposeを優先する仕様になっています。

この仕様からも、DockerComposeが無難と読み取れます。

Docker Composeを使う

インストール

Windowsでは次のコマンドでインストール可能です。

winget install Docker.DockerCompose

コマンド

compose.ymlがあるフォルダで次のコマンドを使用します。

機能 コマンド
起動/再起動 docker-compose up -d
停止(コンテナ削除) docker-compose down
停止(ボリュームを同時削除) docker-compose down -v
停止(pullイメージを同時削除) docker-compose down --rmi all

Composeは Docker/Podmanのコンテナ実行を宣言的に制御するプロダクトであり、主体はコンテナです。そのため、起動後はPodmanのコマンドをそのまま使用できます。

ハイフン無しでも起動できる

DockerとPodmanには、composeというラッパーコマンドがあり、
 docker compose
と呼び出すと、内部でdocker-composeを呼び出します。

Podman環境でdocker composeを呼び出すと、エイリアスによりpodman composeというコマンドが呼び出されるのですが、podmanからDockerComposeを呼び出す形になり次のメッセージが出力されます。

qiita-square

煩わしい場合、次のコマンドでユーザー環境変数を追加することでメッセージの出力を抑制できます。そもそもハイフン付きで起動すれば発生しませんが...

setx PODMAN_COMPOSE_WARNING_LOGS false

Podman Desktopでの状況確認

qiita-square

Containersのセクションで、Composeとその配下のコンテナという形で表示されます。

開発者向けCompose.ymlのサンプル

定義内容の詳細はここでは割愛しますが、各種環境の例を配置しておきます。

リレーショナルDB

開発でのRDB利用には必須となる「初期セットアップ」「SQLクライアントツール」の2要素を含めています。

RDBの起動とともにテーブルの初期構築やテストデータを投入できます。
compose.ymlと同階層にinitフォルダを作成し、そのなかにSQLファイルを置いておきます。
ファイル名昇順で参照し、ファイルに記載されたSQLが実行されます。

.
├── compose.yaml
└── init/
    ├── 01_create_tables.sql
    └── 02_insert_test_records.sql

PostgreSQL

compose.yml
services:
  db:
    image: postgres:16-alpine
    container_name: pg01
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: usr01
      POSTGRES_PASSWORD: pwd01
      POSTGRES_DB: db01
      TZ: "Asia/Tokyo"
    volumes:
      - ./init:/docker-entrypoint-initdb.d:Z
      - pg01-data:/var/lib/postgresql/data

volumes:
  pg01-data:

MariaDB

compose.yml
services:
  db:
    image: mariadb:latest
    container_name: maria01
    environment:
      MYSQL_ROOT_PASSWORD: rootpwd
      MYSQL_DATABASE: db01
      MYSQL_USER: usr01
      MYSQL_PASSWORD: pwd01
    ports:
      - "3306:3306"
    volumes:
      - ./init:/docker-entrypoint-initdb.d:Z
      - maria01-data:/var/lib/mysql

volumes:
  maria01-data:

IBM Db2

Db2は起動に5分くらい時間がかかるため、ログを確認しながら気長に待ちましょう。起動した後の接続ユーザーはdb2inst1になります。
また、Db2は残念ながらinitdbの仕組みに対応していません。

compose.yml
services:
  db:
    image: icr.io/db2_community/db2
    container_name: db2-01
    privileged: true
    environment:
      - LICENSE=accept
      - DB2INST1_PASSWORD=db2inst1pwd
      - DBNAME=db01
      - ARCHIVE_LOGS=false
    ports:
      - "50000:50000"
    volumes:
      - db2-01-data:/database

volumes:
  db2-01-data:

インテグレーション

IBM MQ

IBMのキューを使用した非同期メッセージングのための製品です。
開発者向けには、キューマネージャーに対するメッセージ送信のスタブとしての利用が考えられます。

compose.yml
services:
  ibm-mq:
    image: icr.io/ibm-messaging/mq:latest
    container_name: mq01
    environment:
      - LICENSE=accept
      - MQ_QMGR_NAME=QM1
      - MQ_ADMIN_USER=admin
      - MQ_ADMIN_PASSWORD=passw0rd
      - MQ_APP_USER=app
      - MQ_APP_PASSWORD=apppwd
    ports:
      - "1414:1414"
      - "9443:9443"
    volumes:
      - mq01-data:/mnt/mqm

volumes:
  mq01-data:

MQの利用にあたっては次の記事も参考にしてみてください。

Mailpit

別記事にて紹介した開発環境用に利用できるSMTPサーバーです。
別記事側ではOpenShift上でチーム利用する想定でしたが、こちらは開発者個人向けになります。

compose.yml
services:
  mailpit:
    image: axllent/mailpit
    container_name: mlpt01
    ports:
      - "8025:8025"
      - "1025:1025"
    environment:
      MP_MAX_MESSAGES: 5000

OpenShiftに載せるためのyml定義と比較すると、両者の違いについて理解が進むかもしれません。
余談ですが、compose.ymlを元にOpenShiftへ移行したい場合にはKomposeというツールが役に立ちます。次のようなコマンドでcompose.ymlをdeployment用のymlに変換できます。

kompose convert -f compose.yml

WireMock

APIモックツールで、レスポンスの柔軟性が高く使いやすい印象です。

compose.yml
services:
  wiremock:
    image: wiremock/wiremock:latest
    container_name: wmock
    ports:
      - "8080:8080"
    volumes:
      - ./mappings:/home/wiremock/mappings
      - ./__files:/home/wiremock/__files
    entrypoint: ["/docker-entrypoint.sh", "--global-response-templating", "--disable-gzip", "--verbose"]

次のようなフォルダ構成で、モック動作のレスポンスデータを格納します。

.
├── compose.yaml
├── mappings/    ※APIモック定義のフォルダ
└── __files/    ※レスポンスデータなど

mappingsフォルダに次のようなJSONファイルを配置することで動作します。

hello.json
{
  "request": {
    "method": "GET",
    "url": "/api/hello"
  },
  "response": {
    "status": 200,
    "headers": {
      "Content-Type": "application/json"
    },
    "jsonBody": {
      "totalSize": 1,
      "done": true,
      "records": [
        {
          "message": "Hello Compose!"
        }
      ]
    }
  }
}

ユーティリティなど

Cloud Beaver

SQLクライアントツールである「DBeaver」のブラウザ版です。
compose上に定義したユーザーでログインした後、コネクション定義を行う必要があります。データベースのホスト名は「db」で対象のコンテナを認識できます。「Save credentials for all users with access」のチェックも忘れずに。

compose.yml
services:
  cloudbeaver:
    image: dbeaver/cloudbeaver:latest
    container_name: beaver01
    network_mode: "host"
    volumes:
      - cb01-data:/opt/cloudbeaver/workspace
    environment:
      CB_SERVER_NAME: "LocalBeaver"
      CB_SERVER_URL: "http://localhost:8978"
      CB_ADMIN_NAME: "cbadmin"
      CB_ADMIN_PASSWORD: "cbadminPwd0"

volumes:
  cb01-data:

次のようにRDB定義とセットで1ファイルにまとめることもできます。この場合RDBと同一ネットワークに配置されるため、ホストネットワークとシェアする必要はありません。
こちらのほうがcomposeの本来的な使い方ですね。

compose.yml(RDBとセット)
services:
  db:
    (必要なDBの定義を記載する)

  cloudbeaver:
    image: dbeaver/cloudbeaver:latest
    container_name: beaver01
    ports:
      - "8978:8978"
    volumes:
      - cb01-data:/opt/cloudbeaver/workspace
    environment:
      CB_SERVER_NAME: "LocalBeaver"
      CB_SERVER_URL: "http://localhost:8978"
      CB_ADMIN_NAME: "cbadmin"
      CB_ADMIN_PASSWORD: "cbadminPwd0"
    depends_on:
      - db

volumes:
  (DBのボリューム指定)
  cb01-data:

Keycloak

認証認可の製品です。開発者のローカルでの利用シーンは、認証関連の実装をクイックに行う場合などが考えられますね。

compose.yml
services:
  keycloak:
    image: quay.io/keycloak/keycloak:latest
    container_name: keycloak01
    command: start-dev # 開発モード(HTTPS不要、H2 DB使用)
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
    ports:
      - "8080:8080"

Ollama

ローカルでLLMを動かすためのツールです。ollama自体にGUIが搭載されるようになりましたが、ここでは実績の多く多機能なopen-webuiを使用します。

compose.yml
services:
  ollama:
    image: ollama/ollama:latest
    container_name: olm01
    volumes:
      - ollama_data:/root/.ollama
    ports:
      - "11434:11434"

  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: owu01
    ports:
      - "3000:8080"
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
    volumes:
      - open-webui_data:/app/backend/data
    depends_on:
      - ollama

volumes:
  ollama_data:
  open-webui_data:

使用するモデルは、OllamaのラインナップからOpen WebUI上で指定してD/L可能です。
ministral-3(8b)を指定して動作することを確認しました。「最初の映画ゴジラは昭和何年に公開されましたか?」という質問に1分くらいで回答しています。
Ollamaをコンテナではなくローカルインストールすることで、GPUの性能を活用できる場合もあるようです。この場合、Open WebUIからOllamaが参照できるようにネットワーク設定は修正する必要があります。

LiteLLM

様々なLLM(大規模言語モデル)サービスのAPIを、OpenAI形式(ChatGPTのAPI形式)に統一してくれるオープンソースのプロキシサーバーです。

IBMのwatsonx.aiが直接利用できるAIエージェントなどのツールは増えていますが、未対応の場合もあります。そんなとき、ローカルでLiteLLMをコンテナ起動してここからwatsonx.aiに接続することで対応可能です。

ファイルは次のように配置します。

.
├── compose.yml
├── config.yaml  ※プロキシ設定(モデルの定義)
└── .env         ※APIキーなどの機密情報
compose.yml
services:
  litellm:
    image: ghcr.io/berriai/litellm:main-latest
    container_name: litellm
    ports:
      - "4000:4000"
    volumes:
      - ./config.yaml:/app/config.yaml
    command: [ "--config", "/app/config.yaml" ]
    env_file:
      - .env

次の2ファイルはwatsonx.aiと接続するためのサンプルです。
watsonx.aiでは複数のLLMを使い分けることができます。複数のLLMを定義するにはモデルリストの項目をコピーしてmodelを変更してください。modelに指定する値はwatsonx/(モデルID)になります。

config.yaml
model_list:
  - model_name: gpt-oss-120b
    litellm_params:
      model: watsonx/openai/gpt-oss-120b
      api_key: os.environ/WATSONX_API_KEY
      url: os.environ/WATSONX_URL
      project_id: os.environ/WATSONX_PROJECT_ID

APIキーなどの機密情報はコードに直書きせず、環境変数ファイルで管理します。

.env
LITELLM_MASTER_KEY=XXX(AIツールからLiteLLMに接続するためのキーを任意に指定)

WATSONX_API_KEY=XXX(watsonx.aiのAPIキー)
WATSONX_PROJECT_ID=YYY(watsonx.aiのプロジェクト)
WATSONX_URL=https://ZZZ(watsonx.aiの接続先URL)

その他

AWS開発者はLocalStackなどもよく使われると思います。

Composeの本来の目的である複数サービスの組合せについては、次のサイトにて多くのパターンが提供されています。

おわりに

これらの定義をシェアすることで、チーム内での開発環境構築も捗るのではないでしょうか。
この考え方の延長として、本番運用に適した安定稼働コンテナ稼働環境として発展したといえるのが、k8sやOpenShiftになるかと思います。

ローカル環境でOpenShiftまで導入する必要は小さいですが、Composeに慣れるとk8sやOpenShiftへの移行もスムーズに進むと思います。コンテナネイティブの世界にひとつずつ近づくよう体験していきましょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?