1. 简介
在 Ansible 中使用 Docker Compose 可以简化多容器应用生命周期的自动化管理。但与直接在命令行中运行 docker-compose
相比,其语法并不那么直观。
在本教程中,我们将讨论如何在 Ansible 中使用 Docker Compose,并提供一个实际示例来演示其用法。
2. 创建 Docker Compose 配置文件
与在命令行中使用 Docker Compose 一样,我们需要一个 YAML 格式的配置文件。
下面是一个包含 PostgreSQL 数据库和 Adminer 的多容器应用配置示例:
$ cat docker-compose.yml
services:
database:
image: postgres
restart: always
environment:
POSTGRES_PASSWORD=test
adminer:
image: adminer:latest
restart: always
ports:
- "5000:8080"
depends_on:
- database
⚠️ 注意:我们省略了 version
字段,因为该字段在新版本中已不再推荐使用。
这个 docker-compose.yml
文件会创建一个名为 database
的 PostgreSQL 服务,并设置密码为 test
。在真实项目中,我们通常会使用环境变量等方式来避免硬编码敏感信息。
adminer
服务依赖于 database
服务,因此它会在数据库服务启动后创建,并在数据库服务关闭前停止。同时,adminer
容器的 8080 端口会映射到主机的 5000 端口,因此我们可以通过访问主机的 5000 端口来访问 Adminer。
3. 创建 Ansible Playbook
有了 docker-compose.yml
文件后,接下来我们创建 Ansible playbook 文件 playbook.yml
:
$ cat playbook.yml
- name: Docker Compose in Ansible
hosts: localhost
tasks:
- name: create and start docker compose services
community.docker.docker_compose_v2:
project_src: .
该 playbook 将使用 community.docker.docker_compose_v2
模块来创建并启动我们在 docker-compose.yml
中定义的服务。
参数 project_src
指定包含 docker-compose.yml
的目录。因为我们当前的 playbook 和 compose 文件在同一目录下,所以使用 .
表示当前目录。
如果你的 compose 文件名不是默认的 docker-compose.yml
或 compose.yml
,你需要使用 files
参数显式指定文件名。
例如,如果你的 compose 文件名为 d_compose.yml
,并且位于子目录 sub
中,你可以这样写:
$ cat playbook.yml
...truncated...
tasks:
- name: create and deploy docker compose services
community.docker.docker_compose_v2:
project_src: ./sub
files: d_compose.yml
4. 运行 Ansible Playbook
现在我们来运行这个 playbook:
$ ansible-playbook playbook.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match
'all'
PLAY [Docker Compose in Ansible] ***************************************************************************************
TASK [Gathering Facts] *************************************************************************************************
ok: [localhost]
TASK [create and start docker compose services] ************************************************************************
changed: [localhost]
PLAY RECAP *************************************************************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
我们可以使用 w3m
测试访问 Adminer:
$ w3m http://localhost:5000
Login
System [MySQL ]
Server [db ]
Username [ ]
Password [ ]
Database [ ]
[Login] [ ]Permanent login
Language: [English ] [Use]
Adminer 4.8.1
成功访问 Adminer 页面说明服务已正确启动。
5. 停止并删除容器
当前 playbook 只包含创建和启动容器的任务。如果我们想停止并删除容器,可以添加一个任务:
$ cat playbook.yml
- name: Docker Compose in Ansible
hosts: localhost
tasks:
- name: create and start docker compose services
community.docker.docker_compose_v2:
project_src: .
- name: stop and remove docker compose services
community.docker.docker_compose_v2:
project_src: .
state: absent
但这样运行时会连续执行创建和删除操作。为了避免这种情况,我们可以为每个任务添加 tags
,使其可以独立执行:
$ cat playbook.yml
- name: Docker Compose in Ansible
hosts: localhost
tasks:
- name: create and start docker compose services
community.docker.docker_compose_v2:
project_src: .
tags: create
- name: stop and remove docker compose services
community.docker.docker_compose_v2:
project_src: .
state: absent
tags: destroy
现在我们可以通过指定 tag 来运行特定任务:
✅ 启动服务:
$ ansible-playbook playbook.yml --tags create
✅ 停止并删除服务:
$ ansible-playbook playbook.yml --tags destroy
服务被删除后,再次访问 http://localhost:5000
将失败:
$ w3m http://localhost:5000
w3m: Can't load http://localhost:5000.
但你可以随时重新启动服务。
6. 使用 command 模块
除了使用 community.docker.docker_compose_v2
模块,我们也可以使用 Ansible 的内置 command
模块来运行 Docker Compose 命令:
$ cat playbook.yml
- name: Docker Compose in Ansible
hosts: localhost
tasks:
- name: create and start docker compose services
command: docker compose up -d
tags: create
- name: stop and remove docker compose services
command: docker compose down
tags: destroy
运行测试:
✅ 启动服务:
$ ansible-playbook playbook.yml --tags create
✅ 停止服务:
$ ansible-playbook playbook.yml --tags destroy
⚠️ 但需要注意:虽然 command
模块也能实现功能,但它的幂等性不如 community.docker.docker_compose_v2
模块。随着 playbook 变得复杂,维护起来也会更困难。
7. 总结
在本文中,我们介绍了如何在 Ansible 中使用 Docker Compose:
- 使用
community.docker.docker_compose_v2
模块可以更优雅地管理容器服务生命周期 - 使用
command
模块也可以实现功能,但可维护性较差 - 通过
tags
可以实现任务的按需执行,提高灵活性
✅ 推荐做法:优先使用 community.docker.docker_compose_v2
模块,因其具备更好的幂等性和可读性,适合中大型自动化部署场景。