文章目录
Docker Compose(容器编排)
什么是Docker Compose
docker-compose是Docker官方的开源项目,使用python编写,实现上调用了Docker服务的API进行容器管理及编排,其官方定义为定义和运行多个Docker容器的应用。
docker-compose中两个重要概念:
- 项目(project):由一组关联的应用容器组成的一个完整业务单元,在
docker-compose.yml文件中定义,整个docker-compose.yml定义一个项目。 - 服务(service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
Compose的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。通过compose可以方便的管理多个服务。
为什么要Docker Compose
- Docker是一个轻量化的应用程序,Docker官方推荐每个Docker容器中只运行一个进程。
- 如果一个应用需要涉及到MySQL、nginx等环境,那么需要分别为应用、数据库和nginx创建单独的docker容器,然后分别启动容器。
- 每次启动应用,都至少需要docker run三次或者一些脚本来实现,这样会比较繁琐。
- 另外,这些docker容器都是分散独立的,也不方便镜像管理
Docker Compose的安装
安装docker的时候, 默认已经装了docker-compose,安装的组件名称为docker-compose-plugin。
# 检查安装是否成功
root@139-159-150-152:/data/myworkdir/compose# docker compose version
Docker Compose version v2.16.0
Docker Compose的功能
-
使用步骤
- 使用
docker-compose.yml定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。 - 最后,执行
docker compose up命令来启动并运行整个应用程序。
- 使用
-
核心功能
Compose具有管理应用程序整个生命周期的命令:- 启动,停止和重建服务
- 查看正在运行的服务的状态
- 流式传输运行服务的日志输出
- 在服务上运行一次性命令
Docker Compose使用场景
- 单主机部署:快速搭建一个单节点开发者或者测试环境,方便使用。
- 不同环境隔离:通过指定project来运行不同的环境,实现隔离的目的。
Docker Compose文件 (docker-compose.yml)
文件语法版本
目前官方支持三个大版本,即Version 1、Version 2及Version 3,其中Version 1已经被废弃掉了。
当前最新的版本是3.8,它支持的Docker Engine版本不得低于19.03.0。这里主要基于3.8版本的Compose file语法进行讲解,其他版本介绍参见官方文档。
| Compose file format | Docker Engine release |
|---|---|
| 3.8 | 19.03.0+ |
| 3.7 | 18.06.0+ |
| 3.6 | 18.02.0+ |
| 3.5 | 17.12.0+ |
| 3.4 | 17.09.0+ |
| 3.3 | 17.06.0+ |
| 3.2 | 17.04.0+ |
| 3.1 | 1.13.1+ |
| 3.0 | 1.13.0+ |
| 2.4 | 17.06.0+ |
| 2.3 | 17.06.0+ |
文件基本结构及常见指令
version: "3.8" # 定义版本,表示当前使用的docker-compose语法的版本
services: # 服务,可以存在多个
servicename: # 服务名字,它也是内部bridge网络可以使用的 DNS name,如果不是集群模式相当于docker run 的时候指定的一个名称
# 集群(swarm)模式下是多个容器的逻辑抽象
command: # 可选,如果设置了,则会覆盖默认镜像里的CMD命令
image: # 必选,镜像的名字,I则会根据镜像里的
environment: # 可选,等价于 docker container run里的 --env 选项 设置环境变量
volumes: # 可选,等价于 docker container run里的 -v 选项 绑定数据卷
networks: # 可选,等价于 docker container run里的 --network 选项 指定网络
ports: # 可选,等价于 docker container run里的 -p 选项指定端口映射
expose: # 可选,指定容器暴露的端口
build: # 构建目录,指定dockerfile的端口
depends_on: # 服务的依赖配置
env_file: # 环境变量文件
service2:
image:
command:
networks:
ports:
service3:
...
volumes: # 可选,等价于 docker volume create
networks: # 可选,等价于 docker network create
常见字段格式语法
image
指定容器运行的镜像。以下格式都可以:
image: redis
image: redis:5
image: ha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398bc4b991aac7
image: library/redis
image: docker.io/library/redis
image: my.private.registry:5000/redis
command
覆盖容器启动的默认命令。
command: ["bundle", "exec", "thin", "-p", "3000"]
command: bundle exec thin -p 3000
entrypoint
覆盖容器默认的entrypoint。
entrypoint: /code/entrypoint.sh
也可以是以下格式:
entrypoint:
- php
- -d
- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
- -d
- memory_limit=-1
- vendor/bin/phpunit
environment
添加环境变量。可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保YML解析器不会将其转换为True或False。
- map语法
environment:
SHOW: 'true'
USER_INPUT: development
RACK_ENV: development
- 数组语法
environment:
- RACK_ENV=development
- SHOW=true
- USER_INPUT
networks
指定容器运行的网络:
- 配置容器网络
services:
frontend:
image: awesome/webapp
networks:
- front-tier
- back-tier
monitoring:
image: awesome/monitoring
networks:
- admin
backend:
image: awesome/backend
networks:
back-tier:
aliases:
- database
admin:
aliases:
- mysql
networks:
front-tier:
back-tier:
admin:
- 配置网络驱动和子网信息
services:
frontend:
image: awesome/webapp
networks:
front-tier:
ipv4_address: 172.16.238.10
networks:
front-tier:
ipam:
driver: default
config:
- subnet: "172.16.238.0/24"
volumes
将主机的数据卷或者文件挂载到容器里。
- 短语法:
services:
db:
image: postgres:latest
volumes:
- "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
- "/localhost/data:/var/lib/postgresql/data"
- 完整语法:
services:
backend:
image: awesome/backend
volumes:
- type: volume
source: dbdata
target: /data
volume:
nocopy: true
- type: bind
source: ./var/run/postgres/postgres.sock
target: /var/run/postgres/postgres.sock
volumes:
dbdata:
ports
指定端口映射。以下格式都可以:
- 短语法:
ports:
- "3000"
- "8979:80"
- "127.0.0.1:8080:80"
- 长语法:
ports:
- target: 80
published: 8080
protocol: tcp
mode: host
- target: 8000-9000
published: 8000-9000
protocol: tcp
mode: host
- 端口语法:
ports:
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
- "6060:6060/udp"
expose
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数:
expose:
- "3000"
- "8000"
build
指定为构建镜像上下文路径:
例如webapp服务,指定为从上下文路径./dir/Dockerfile所构建的镜像。
version: "3.7"
services:
webapp:
build: ./dir
或者,作为具有在上下文指定的路径的对象,以及可选的Dockerfile和args:
version: "3.7"
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
context:上下文路径,镜像的Dockerfile文件所在的文件夹dockerfile:指定构建镜像的Dockerfile的文件名args:添加构建参数,这是只能在构建过程中访问的环境变量。labels:设置构建镜像的标签。
depends_on
设置依赖关系:
docker compose up:以依赖性顺序启动服务。在示例中,先启动db和redis,才会启动web。
docker compose up SERVICE:自动包含SERVICE的依赖项。在以下示例中,docker compose up web也会创建并启动db和redis。
docker compose stop:按依赖关系顺序停止服务。在以下示例中,web在db和redis之前停止。
version: "3.7"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
可以指定条件,方便的配置健康检查来完成:
services:
web:
build: .
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
redis:
image: redis
db:
image: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
healthcheck样例:
services:
web:
image: nginx:1.24.0
environment:
TEST: 1
ports:
- 8979:80
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: "bit@123"
volumes:
- /data/maxhou/mysqldata/varlib/:/var/lib/mysql
healthcheck:
test: mysql -user=root --password='bit@123' -e "SELECT 1;"
interval: 10s
timeout: 5s
retries: 10
redis:
image: redis:7
healthcheck:
test: redis-cli ping
interval: 10s
timeout: 5s
retries: 10
env_file
从文件添加环境变量。可以是单个值或列表的多个值。
env_file: .env
也可以是列表格式:
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
Docker Compose命令
| 命令 | 功能 |
|---|---|
| docker compose build | 构建服务 |
| docker compose config | 验证并查看compose文件配置 |
| docker compose cp | 在本地和服务容器之间拷贝文件 |
| docker compose create | 创建服务的容器 |
| docker compose down | 停止并删除容器、网络、卷、镜像 |
| docker compose events | 从服务器接收实时事件 |
| docker compose exec | 在运行的容器中执行命令 |
| docker compose images | 列出所有容器使用的镜像 |
| docker compose kill | 强制停止服务的容器 |
| docker compose logs | 显示日志 |
| docker compose ls | 显示所有项目 |
| docker compose pause | 暂停服务 |
| docker compose port | 列出所有的端口映射 |
| docker compose ps | 该命令可以列出项目中目前的所有容器 |
| docker compose pull | 拉取服务镜像 |
| docker compose push | 推送服务镜像 |
| docker compose restart | 重启或者重启某个服务 |
| docker compose rm | 删除服务停止的容器 |
| docker compose run | 在指定服务器上执行相关的命令 |
| docker compose start | 启动当前停止的某个容器 |
| docker compose stop | 停止当前运行的某个容器 |
| docker compose top | 显示运行的进程 |
| docker compose unpause | 恢复服务 |
| docker compose up | up命令会构建,(重新)创建,启动,链接一个服务相关的容器。情况如下如果容器已经存在,将会停止并尝试重新创建他们。并使用之前挂载的卷。–no-recreate参数可以让容器不被停止或者重新创建,-d表示后台运行 |
| docker compose version | 查看版本 |
命令格式
对于Compose来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的服务或者容器。如果没有特别的说明,命令对象将是项目,这意味着项目中所有的服务都会受到命令影响。
docker-compose命令的基本的使用格式为
docker compose [OPTIONS] COMMAND [ARGS...]
常见选项说明
-f, --file指定使用的Compose模板文件,默认为docker-compose.yml,可以多次指定-p, --project-name指定项目名称,默认将使用所在目录名称作为项目名
常见命令说明
up
该命令的作用十分强大,它会尝试自动完成包括构建镜像、(重新)创建服务、启动服务并关联服务相关容器的一系列操作,可以直接通过该命令来启动一个项目。
docker compose up [options] [SERVICE...]
-d在后台运行服务容器,推荐在生产环境下使用该选项--force-recreate强制重新创建容器,不能与--no-recreate同时使用--no-recreate如果容器已经存在了,则不重新创建,不能与--force-recreate同时使用
down
停止所有容器,并删除容器和网络
docker compose down [options] [SERVICE...]
-v, --volumes删除容器同时删除目录映射
run
该命令可以在指定服务器上执行相关的命令 (注意这里启动的是yml文件中配置好的服务,而不是镜像)
docker compose run [options] SERVICE [COMMAND] [ARGS...]
-d后台运行容器--name NAME为容器指定一个名字--entrypoint CMD覆盖默认的容器启动指令-e KEY=VAL设置环境变量值,可多次使用选项来设置多个环境变量-u, --user=""指定运行容器的用户名或者uid--rm运行命令后自动删除容器-p, --publish=[]映射容器端口到本地主机
# 例如:启动一个 ubuntu 服务器容器,并执行 ping docker.com 命令
docker compose run ubuntu ping docker.com
操作案例
Docker Compose基本操作
- 创建compose目录
mkdir -p /data/myworkdir/compose/base
cd /data/myworkdir/compose/base
- 进入base目录,创建docker-compose.yml文件
cd /data/myworkdir/compose/base/
vi docker-compose.yml
- 编写为以下内容:
version: 3.8
services:
web:
image: nginx:1.24.0
environment:
TEST: 1
ports:
- 8979:80
networks:
- mytestnet
volumes:
- ./mynginxhome:/usr/share/nginx/html
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: "bit@123"
networks:
- mytestnet
volumes:
- /data/maxhou/mysqldata/varlib/:/var/lib/mysql
healthcheck:
test: mysql -user=root --password='bit@123' -e "SELECT 1;"
interval: 10s
timeout: 5s
retries: 10
redis:
image: redis:7
networks:
- mytestnet
healthcheck:
test: redis-cli ping
interval: 10s
timeout: 5s
retries: 10
networks:
mytestnet:
- 输入docker config会做检查
root@139-159-150-152:/data/myworkdir/compose/base# docker compose config
version must be a string
- 修改错误信息,将版本转为字符串,再次检查
services:
web:
image: nginx:1.24.0
environment:
TEST: 1
ports:
- 8979:80
networks:
- mytestnet
volumes:
- ./mynginxhome:/usr/share/nginx/html
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: "bit@123"
networks:
- mytestnet
volumes:
- /data/maxhou/mysqldata/varlib/:/var/lib/mysql
healthcheck:
test: mysql -user=root --password='bit@123' -e "SELECT 1;"
interval: 10s
timeout: 5s
retries: 10
redis:
image: redis:7
networks:
- mytestnet
healthcheck:
test: redis-cli ping
interval: 10s
timeout: 5s
retries: 10
networks:
mytestnet:
root@139-159-150-152:/data/myworkdir/compose/base# docker compose config
name: base
services:
mysql:
environment:
MYSQL_ROOT_PASSWORD: bit@123
healthcheck:
test:
- CMD-SHELL
- mysql -user=root --password='bit@123' -e "SELECT 1;"
timeout: 5s
interval: 10s
retries: 10
image: mysql:5.7
networks:
mytestnet: null
volumes:
- type: bind
source: /data/maxhou/mysqldata/varlib/
target: /var/lib/mysql
bind:
create_host_path: true
redis:
healthcheck:
test:
- CMD-SHELL
- redis-cli ping
timeout: 5s
interval: 10s
retries: 10
image: redis:7
networks:
mytestnet: null
web:
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
environment:
TEST: "1"
image: nginx:1.24.0
networks:
mytestnet: null
ports:
- target: 80
published: 8979
protocol: tcp
mode: ingress
volumes:
- type: bind
source: /data/myworkdir/compose/base/mynginxhome
target: /usr/share/nginx/html
bind:
create_host_path: true
networks:
mytestnet:
name: base_mytestnet
- 创建首页目录,编辑首页内容
root@139-159-150-152:/data/myworkdir/compose/base# mkdir -p mynginxhome
root@139-159-150-152:/data/myworkdir/compose/base/mynginxhome#
echo "Hello bit" > index.html
- 启动服务
root@139-159-150-152:/data/myworkdir/compose/base# docker compose up -d
[+] Running 4/4
✔ Network base_mytestnet Created
✔ Container base-mysql-1 Healthy
✔ Container base-redis-1 Healthy
✔ Container base-web-1 Started
- 通过页面访问
http://139.159.150.152:8979
Hello bit
- 停止服务
root@139-159-150-152:/data/myworkdir/compose/base# docker compose stop
[+] Running 3/3
✔ Container base-web-1 Stopped
✔ Container base-mysql-1 Stopped
✔ Container base-redis-1 Stopped
- 启动服务
root@139-159-150-152:/data/myworkdir/compose/base# docker compose start
[+] Running 3/3
✔ Container base-redis-1 Healthy
✔ Container base-mysql-1 Healthy
✔ Container base-web-1 Started
- 删除服务
root@139-159-150-152:/data/myworkdir/compose/base# docker compose down
[+] Running 4/4
✔ Container base-web-1 Removed
✔ Container base-redis-1 Removed
✔ Container base-mysql-1 Removed
✔ Network base_mytestnet Removed
综合案例
Docker Compose部署WordPress
WordPress是使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站。也可以把WordPress当作一个内容管理系统(CMS)来使用。
部署WordPress
- 编写Docker Compose
#指定 docker-compose.yml 文件的版本
version: '3.8'
# 定义所有的 service 信息, services 下面的第一级别的 key 既是一个 service 的名称
services:
db:
image: mysql:5.7
volumes:
- ./db_data:/var/lib/mysql
# 定义容器重启策略
restart: always
# 设置环境变量, environment 的值可以覆盖 env_file 的值
environment:
MYSQL_ROOT_PASSWORD: mywordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
healthcheck:
test: mysql --user=root --password='mywordpress' -e "SELECT 1;"
interval: 10s
timeout: 5s
retries: 10
wordpress:
#docker compose up 以依赖顺序启动服务,先启动db
depends_on:
db:
condition: service_healthy
image: wordpress:latest
# 建立宿主机和容器之间的端口映射关系,容器的 80 端口和宿主机的 8000 端口建立映射关系
ports:
- "8000:80"
restart: always
volumes:
- ./wordpress:/var/www/html
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
- 运行站点
docker compose up -d
-
访问web页面,配置参数,点击安装,登录:

-
删除,释放空间
root@139-159-150-152:/data/myworkdir/compose# docker compose down
[+] Running 3/2
✔ Container compose-wordpress-1 Removed
3.3s
✔ Container compose-db-1 Removed
1.9s
✔ Network compose_default Removed
常见问题
-
up、run和start之间有什么区别
通常,你想要docker compose up。用于up启动或重新启动docker-compose.yml.在默认的"附加"模式下,会看到来自所有容器的所有日志。在"分离"模式(-d)中,启动容器后Compose退出,但容器继续在后台运行。
docker compose run命令用于运行"一次性"或"临时"任务。它需要您要运行的服务名称,并且只为正在运行的服务所依赖的服务启动容器。用于run运行测试或执行管理任务,例如从数据卷容器中删除或添加数据。该run命令的作用类似于docker run -ti它打开容器的交互式终端并返回与容器中进程的退出状态匹配的退出状态。
docker compose start命令仅对重新启动先前创建但已停止的容器有用。它从不创建新容器。 -
如何在同一主机上运行Compose文件的多个副本
Compose使用项目名称为项目的所有容器和其他资源创建唯一标识符。要运行项目的多个副本,使用 -p命令行选项或COMPOSE_PROJECT_NAME环境变量 设置自定义项目名称。 -
如何控制服务启动顺序?
可以控制启动顺序,通过依赖指定,并且可以配合healthcheck等健康检查成功以后再启动。

6万+

被折叠的 条评论
为什么被折叠?



