Docker Composeで1台の管理はできても、複数サーバーへの一括展開となると途端に手が止まる——そんな状況は、Ansibleのcommunity.dockerコレクションを使えば解決できます。
この記事では、AnsibleからDockerコンテナを一括管理する方法を解説します。
community.dockerコレクションのインストールから、docker_containerモジュールによるコンテナのデプロイ・停止・削除、ネットワークとボリュームのPlaybook管理まで、RHEL 9.4 / Ubuntu 24.04 LTSで動作確認した実例を交えて紹介します。
この記事のポイント
・ docker_containerモジュールでコンテナのデプロイ・停止・削除を1つのPlaybookで管理できる
・ community.dockerコレクションはansible-galaxy collection installで導入する
・ loopを使えば複数コンテナをまとめて一括起動・停止できる
・ docker_networkとdocker_volumeでネットワークとVolumeもコード管理できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜAnsibleでDockerコンテナを管理するのか
現場でよくある問題として、「docker runコマンドを手で打ったはずなのに先月と微妙に引数が違う」「新しいサーバーを追加したら、そのサーバーだけコンテナが古い設定で動いている」というものがあります。Ansibleでコンテナ管理を行うことで、以下のメリットが得られます。
・PlaybookがそのままドキュメントになるYAML記述:コンテナの設定を人間が読める形でコードに記録します
・冪等性による安全な再実行:すでに起動中のコンテナには手を加えず、差分だけを更新します
・複数サーバーへの同時展開:inventoryに書いたすべてのサーバーに対して、1回のansible-playbookで一括適用できます
Docker Composeはあくまで「1台のホスト上の複数コンテナ管理」が得意です。複数ホストにまたがる展開や、既存のAnsibleワークフローへの組み込みには、community.dockerコレクションが適しています。
準備:community.dockerコレクションのインストール
1. Ansibleのバージョンを確認する
community.dockerコレクションはAnsible 2.9以降が必要です。まずコントロールノード(自分のPC)でバージョンを確認します。ansible --version
ansible [core 2.16.4] config file = /etc/ansible/ansible.cfg configured module search path = ['/home/admin/.ansible/plugins/modules'] ansible python module location = /usr/lib/python3.11/site-packages/ansible ansible collection location = /home/admin/.ansible/collections executable location = /usr/bin/ansible python version = 3.11.6 (main, Nov 14 2023, 09:36:21)
2. community.dockerコレクションをインストールする
ansible-galaxyコマンドでコレクションをインストールします。ansible-galaxy collection install community.docker
Starting galaxy collection install process Process install dependency map Starting collection install process Downloading https://galaxy.ansible.com/download/community-docker-3.10.4.tar.gz Installing 'community.docker:3.10.4' to '/home/admin/.ansible/collections/...' community.docker:3.10.4 was installed successfully
pip3 list | grep docker
docker 6.1.3
pip3 install docker
docker_containerモジュールの基本:コンテナをデプロイする
1. 最初のPlaybookを作る
docker_containerモジュールを使って、Nginxコンテナをデプロイする最小構成のPlaybookです。# deploy_nginx.yml --- - name: Dockerコンテナ管理サンプル hosts: webservers become: yes tasks: - name: Nginxコンテナを起動する community.docker.docker_container: name: nginx_app image: nginx:1.26 state: started restart_policy: always ports: - "8080:80"
・state: started — コンテナが起動していなければ起動する(すでに起動中なら何もしない)
・restart_policy: always — ホストの再起動時にDockerデーモンが自動でコンテナを再起動する
・ports: "8080:80" — ホストの8080番ポートをコンテナの80番にマッピングする
2. Playbookを実行してコンテナを起動する
インベントリファイルに対象サーバーを記述してPlaybookを実行します。# inventory.ini [webservers] 192.168.1.101 192.168.1.102 ansible-playbook -i inventory.ini deploy_nginx.yml
PLAY [Dockerコンテナ管理サンプル] ************************************* TASK [Gathering Facts] ************************************************ ok: [192.168.1.101] ok: [192.168.1.102] TASK [Nginxコンテナを起動する] *************************************** changed: [192.168.1.101] changed: [192.168.1.102] PLAY RECAP ************************************************************ 192.168.1.101 : ok=2 changed=1 unreachable=0 failed=0 192.168.1.102 : ok=2 changed=1 unreachable=0 failed=0
TASK [Nginxコンテナを起動する] *************************************** ok: [192.168.1.101] ok: [192.168.1.102]
3. コンテナを停止・削除する
state: stoppedでコンテナを停止、state: absentで削除します。# コンテナを停止する - name: Nginxコンテナを停止する community.docker.docker_container: name: nginx_app state: stopped # コンテナを削除する(停止もあわせて行う) - name: Nginxコンテナを削除する community.docker.docker_container: name: nginx_app state: absent
複数コンテナをloopで一括管理する
1. loopで複数コンテナを一括起動する
loopを使うことで、同じ設定の複数コンテナをまとめて管理できます。サービスごとにタスクを書き並べるよりもPlaybookがコンパクトになり、追加・削除もvarsリストの編集だけで済みます。# multi_containers.yml --- - name: 複数コンテナを一括管理 hosts: appservers become: yes vars: app_containers: - { name: "api_v1", image: "myapp:1.0", port: "8001:8080" } - { name: "api_v2", image: "myapp:2.0", port: "8002:8080" } - { name: "worker_1", image: "myworker:latest", port: "8003:8080" } tasks: - name: アプリコンテナを一括起動 community.docker.docker_container: name: "{{ item.name }}" image: "{{ item.image }}" state: started restart_policy: always ports: - "{{ item.port }}" loop: "{{ app_containers }}"
2. 環境変数とポートマッピングの設定
本番環境では、コンテナに環境変数でDBパスワードやAPIキーを渡すことが多いです。envパラメータで設定します。【注意】Playbookに平文でパスワードを書くことは絶対に避けてください。機密情報はAnsible Vaultで暗号化してvarsファイルに保存し、Playbookからはvault変数を参照する運用が鉄則です。
# group_vars/all/vault.yml(Vaultで暗号化) db_root_password: "(Vaultで管理)" db_user_password: "(Vaultで管理)" # db_deploy.yml - name: DBコンテナを起動する(環境変数設定あり) community.docker.docker_container: name: mysql_db image: mysql:8.0 state: started restart_policy: unless-stopped env: MYSQL_ROOT_PASSWORD: "{{ db_root_password }}" MYSQL_DATABASE: "myapp" MYSQL_USER: "appuser" MYSQL_PASSWORD: "{{ db_user_password }}" ports: - "3306:3306" volumes: - /data/mysql:/var/lib/mysql
DockerネットワークとVolumeをPlaybookで管理する
1. docker_networkモジュールでカスタムネットワークを作る
複数のコンテナを同じネットワーク上に配置したい場合、docker_networkモジュールで先にネットワークを作成します。同じネットワーク上のコンテナはコンテナ名でDNS解決できるため、サービス間通信がシンプルになります。# network_setup.yml --- - name: Dockerネットワーク設定 hosts: appservers become: yes tasks: - name: アプリ用Dockerネットワークを作成する community.docker.docker_network: name: app_network driver: bridge state: present - name: フロントエンドコンテナをapp_networkに接続する community.docker.docker_container: name: nginx_frontend image: nginx:1.26 state: started networks: - name: app_network
docker network ls NETWORK ID NAME DRIVER SCOPE a3f2b1c4d5e6 app_network bridge local b7c8d9e0f1a2 bridge bridge local c3d4e5f6a7b8 host host local
2. docker_volumeモジュールでデータVolumeを管理する
データの永続化には名前付きVolumeが便利です。docker_volumeモジュールでVolumeの作成・削除をコード管理します。# volume_and_container.yml --- - name: VolumeとDBコンテナの管理 hosts: dbservers become: yes tasks: - name: DBデータ用Volumeを作成する community.docker.docker_volume: name: mysql_data state: present - name: MySQLコンテナをVolume付きで起動する community.docker.docker_container: name: mysql_db image: mysql:8.0 state: started volumes: - mysql_data:/var/lib/mysql
docker volume ls DRIVER VOLUME NAME local mysql_data
実務Tips:冪等性を維持したコンテナ管理のコツ
Docker管理でよくある落とし穴が、imageを更新したのにコンテナが古いままになる問題です。community.dockerコレクションのdocker_containerモジュールは、デフォルトでは「コンテナが起動しているかどうか」だけを見て冪等性を判断します。イメージのタグが同じであればコンテナを再作成しません。新しいイメージを確実に反映させたい場合は、image_name_mismatch: recreateとpull: alwaysを組み合わせます。
- name: Nginxコンテナを常に最新イメージで起動する community.docker.docker_container: name: nginx_app image: nginx:1.26 state: started pull: always image_name_mismatch: recreate
- name: Nginxコンテナにヘルスチェックを設定する community.docker.docker_container: name: nginx_app image: nginx:1.26 state: started healthcheck: test: ["CMD", "curl", "-f", "http://localhost/"] interval: 30s timeout: 10s retries: 3
トラブルシュート|よくあるエラーと対処法
【エラー1】「Failed to import the required Python library (docker)」
管理対象サーバーにPythonのdocker SDKがインストールされていない場合に発生します。Ansibleのpipモジュールで先にインストールするタスクをPlaybookの先頭に追加します。- name: docker SDKをインストールする ansible.builtin.pip: name: docker state: present
【エラー2】「Got permission denied while trying to connect to the Docker daemon socket」
AnsibleがSSH接続するユーザーがdockerグループに属していない場合に発生します。Playbookのbecome: yesでrootとして実行するか、対象ユーザーをdockerグループに追加します(追加後は再ログインが必要です)。# dockerグループへの追加(対象サーバーで実行) sudo usermod -aG docker ansible_user
【エラー3】コンテナのstateが毎回「changed」になり続ける
コンテナを構成するパラメータ(ポート・環境変数・ラベル等)がPlaybookの記述と実際のコンテナ設定で一致していない場合に発生します。docker inspectで実際の設定を確認し、Playbookとの差分を特定します。# コンテナの実際の設定を確認する docker inspect nginx_app
本記事のまとめ
| やりたいこと | モジュール・パラメータ |
|---|---|
| コンテナを起動する | community.docker.docker_container: state: started |
| コンテナを停止する | community.docker.docker_container: state: stopped |
| コンテナを削除する | community.docker.docker_container: state: absent |
| 複数コンテナの一括管理 | docker_container + loop: "{{ app_containers }}" |
| Dockerネットワークの作成 | community.docker.docker_network: state: present |
| Volumeの作成 | community.docker.docker_volume: state: present |
| イメージ更新時のコンテナ再作成 | docker_container: image_name_mismatch: recreate |
Ansible実践ハンズオンの詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます