1、Compose简介
Docker Compose是Docker官方的编排工具,可以让用户通过编写一个简单的模板文件,快递的创建和管理基于Docker容器的应用集群,负责实现对Docker容器集群进行快速编排。
我们知道使用一个Dockerfile模板文件,可以让用户很方便地定义一个单独的应用容器。然而在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况,Compose恰好满足了这样的需求,它允许用户通过一个单独的docker-compose.yml模板文件(YAML格式)来定义一组相关联的应用容器为一个项目。
2、Compose两个重要概念
对于Compose来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的服务或者容器。
Compose命令的基本使用格式:
docker-compose [ -f=
命令选项如下
| 命令选项 | 说明 |
| -f, --file FILE | 指定使用的Compose模板文件,默认为docker-compose.yml,可以多次指定 |
| -p, --project-name NAME | 指定项目名称,默认将使用所在目录名称作为项目名 |
| --x-networking | 使用Docker的可拔插网络后端特性 |
| --x-network-driver DRIVER | 指定网络后端的驱动,默认为bridge |
| --verbose | 输出更多调试信息 |
| -v, --version | 打印版本并退出 |
Compose命令
| 命令 | 说明 |
| build | 构建项目中的服务容器 |
| help | 获得一个命令的帮助 |
| kill | 通过发送SIGKILL信号来强制停止服务容器 |
| logs | 查看服务容器的输出 |
| pause | 暂停一个服务容器 |
| port | 打印某个容器端口所映射的公共端口 |
| ps | 列出项目中目前的所有容器 |
| pull | 拉取服务依赖的镜像 |
| restart | 重启项目中的服务 |
| rm | 删除所有(停止状态的)服务容器 |
| run | 在指定服务上执行一个命令 |
| scale | 设置指定服务运行的容器个数 |
| start | 启动已经存在的服务容器 |
| stop | 停止已经处于运行状态的容器,但不删除它 |
| unpause | 恢复处于暂停状态中的服务 |
| up | 自动完成包括构建镜像、创建服务、启动服务并关联服务相关容器的一系列操作 |
| migrate-to-labels | 重新创建容器,并添加label |
| version | 打印版本信息 |
命令使用说明
1、build
docker-compose build [ options ] [ SERVICE... ]:构建(重新构建)项目中的服务容器
选项包括:
2、help
获得一个命令的帮助
3、kill
docker-compose kill [ options ] [ SERVICE... ]:通过发送SIGKILL信号来强制停止服务容器
4、logs
docker-compose logs [ options ] [ SERVICE... ]:查看服务容器的输出,默认情况下docker-compose将对不同的服务输出使用不同的颜色来区分。可以通过--no-color来关闭颜色
5、pause
docker-compose pause [ SERVICE... ]:暂停一个服务容器
6、port
docker-compose port [ options ] SERVICE PRIVATE_PORT:显示某个容器端口所映射的公共端口
选项:
7、ps
docker-compose ps [ options ] [ SERVICE... ]:列出项目中目前的所有容器,选项-q只打印容器的ID信息
8、pull
docker-compose pull [ options ] [ SERVICE... ]:拉取服务依赖的镜像,选项--ignore-pull-failures忽略拉取镜像过程中的错误
9、restart
docker-compose restart [ options ] [ SERVICE... ]:重启项目中的服务,选项-t,--timeout TIMEOUT指定重启前停止容器的超时(默认为10s)
10、rm
docker-compose rm [ options ] [ SERVICE... ]:删除所有(停止状态的)服务容器。推荐先执行docker-compose stop命令来停止容器
11、run
docker-compose run [ options ] [-p PORT...] [-e KEY=VALUE...] SERVICE [COMMAND] [ARGS...]:在指定服务上执行一个命令
选项:
12、scale
docker-compose scale [ options ] [SERVICE=NUM...]:设置指定服务运行的容器个数
通过service=num的参数来设置数量,例如docker-compose scale web=3 db=2,当指定数目多于该服务当前实际运行容器,将新创建并启动容器,反之将停止容器
13、start
docker-compose start [ SERVICE... ]:启动已经存在的服务容器
14、stop
docker-compose stop [ options ] [ SERVICE... ]:停止已经处于运行状态的容器,但不删除它
15、unpause
docker-compose unpause [ SERVICE... ]:恢复处于暂停状态中的服务
16、up
docker-compose up [ options ] [ SERVICE... ]:自动完成构建镜像、创建服务、启动服务,并关联服务相关容器的一系列操作
选项:
17、migrate-to-labels
docker-compose migrate-to-labels:重新创建容器,并添加label
18、version
docker-compose version:打印版本信息
环境变量可以用来配置Compose的行为
| 变量 | 说明 |
| COMPOSE_PROJECT_NAME | 设置Compose的项目名称,默认是当前工作目录(docker-compose.yml文件所在目录)的名字 Compose会为每一个启动的容器前添加的项目名称,例如一个名称为proj的项目,其中的一个web容器,名称可能为proj_web_1 |
| COMPOSE_FILE | 设置要使用的docker-compose.yml的路径。如果不指定,默认会先查找当前工作目录是否存在docker-compose.yml文件,如果找不到,则继续查找上层目录 |
| COMPOSE_API_VERSION | 指定API版本 |
| DOCKER_HOST | 设置Docker服务端的监听地址 |
| DOCKER_TLS_VERIFY | 如果该环境变量不为空,则与Docker服务端的所有交互都通过TLS协议进行加密 |
| DOCKER_CERT_PATH | 配置TLS通信所需要的验证文件(包括ca.pem、cert.pem和key.pem)的路径,默认是~/.docker |
| COMPOSE_HTTP_TIMEOUT | Compose发送往Docker服务端的请求的超时,默认为60s |
version: "2"
services:
webapp:
image: examples/web
ports:
- "80:80"
volumes:
- "/data"
每个服务都必须通过image指令指定镜像或build指令等来自动构建生成镜像,如果使用build指令,在Dockerfile中设置的选项将会自动被获取,无需在docker-compose.yml中再次设置
相关指令:
| 指令 | 功能 |
| build | 指定服务镜像Dockerfile所在路径 |
| cap_add, cap_drop | 指定容器的内核能力分配 |
| command | 覆盖容器启动后默认执行的命令 |
| cgroup_parent | 指定父cgroup组,意味着将继续该组 |
| container_name | 指定容器名称,默认将会使用项目名称_服务名称_序号这样的格式 |
| devices | 指定设备映射关系 |
| dns | 自定义DNS服务器,可以是一个值,也可以是一个列表 |
| dns_search | 配置DNS搜索域,可以是一个值,也可以是一个列表 |
| dockerfile | 指定额外编译镜像的Dockerfile文件,可以通过该指令来指定 |
| env_file | 从文件中获取环境变量,可以为单独的文件路径或列表 |
| environment | 设置环境变量,可以使用数组或字典两种格式 |
| expose | 暴露端口 |
| extends | 基于其他模板文件进行扩展 |
| external_links | 链接到docker-compose.yml外部的容器,甚至可以是非Compose管理的外部容器 |
| extra_hosts | 指定额外的host名称映射信息 |
| image | 指定为镜像名称或镜像ID。如果镜像在本地不存在,Compose将会尝试拉取这个镜像 |
| labels | 为容器添加Docker元数据信息 |
| links | 链接到其他服务中的容器,输入需要链接的容器服务名称即可 |
| log_driver | 指定日志驱动类型,类似于Docker中的--log-driver参数,目前支持三种日志驱动类型:json-file,syslog,none |
| log_ppt | 日志驱动的相关参数 |
| net | 设置网络模式。参数类似于docker client的--net参数一样 |
| pid | 跟主机系统共享进程命名空间,打开该选项的容器之间,以及容器和宿主机系统之间可以通过进程ID来相互访问和操作 |
| ports | 暴露端口信息 |
| security_opt |
指定容器模板标签(label)机制的默认属性(如用户、角色、类型、级别等) |
| ulimits | 指定容器的ulimits限制值 |
| volumes | 数据卷所挂载路径设置,可以设置宿主机路径(HOST:CONTAINER)或加上访问模式(HOST:CONTAINER:ro) |
| volumes_driver | 较新版本的Docker支持数据卷的插件驱动 |
| volumes_from | 从另一个服务或容器挂载它的数据卷 |
指令用法:
1、build指令
指定Dockerfile所在文件夹的路径(可以是绝对路径,或者相对docker-compose.yml文件的路径),Compose将会利用它自动构建这个镜像,然后使用这个镜像:
build: /path/to/build/dir
build:
context: .
dockerfile: dockerfile_master
2、cap_add,cap_drop指令
指定容器的内核能力分配,例如容器拥有所有能力可以指定为:
cap_add:
- ALL
去掉NET_ADMIN能力可以指定为:
cap_drop:
- NET_ADMIN
3、command指令
覆盖容器启动后默认执行的命令:
command: echo "hello world"
4、cgroup_parent指令
指定父cgroup组,意味着将继承该组的资源限制,例如创建一个cgroup组名称为cgroups_1
cgroup_parent: cgroups_1
5、container_name指令
指定容器名称,默认将会使用项目名称_服务名称_序号这样的格式
container_name: docker-web-container
需要注意,指定容器名称后,该服务将无法进行扩展,因为Docker不允许多个容器具有相同的名称
6、devices指令
指定设备映射关系
devices:
- "/dev/ttyUSB1:/dev/ttyUSB0"
7、dns指令
自定义DNS服务器,可以是一个值,也可以是一个列表
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
8、dns_search指令
配置DNS搜索域,可以是一个值,也可以是一个列表
dns_search: example.com
dns_search:
- domain1.example.com
- domain2.example.com
9、dockerfile指令
如果需要,指定额外的编译镜像的Dockerfile文件,可以通过该指令来指定
dockerfile: Dockerfile-alternate
10、env_file指令
从文件中获取环境变量,可以为单独的文件路径或列表
如果通过docker-compose -f FILE方式来指定Compose模板文件,则env_file中变量的路径会基于模板文件路径
如果有变量名称与environment指令冲突,则按照惯例,以后者为准
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
环境变量文件中每一行必须符合格式,以common.env为例
# common.env: Set development environment
PROG_ENV=development
11、environment指令
设置环境变量,可以使用数组或字典两种格式
只给定名称的变量会自动获取运行Compose主机上对应变量的值,可以用来防止泄露不必要的数据
# SESSION_SECRET会自动获取运行Compose主机上对应变量的值
environment:
RACK_ENV: development
SESSION_SECRET:
environment:
- RACK_ENV = development
- SESSION_SECRET
注意,如果变量名称或者值中用到 true | false,yes | no 等表达布尔含义的词汇,最好放到引号里,避免YAML自动解析某些内容为对应的布尔语义
12、expose指令
暴露端口,但不映射到宿主机,只允许能被连接的服务访问,仅可以指定内部端口为参数
expose:
- "3000"
- "8000"
13、extends指令
基于其他模板文件进行扩展,例如我们已经有一个webapp服务,定义一个基础模板文件为common.yml
# common.yml
webapp:
build: ./webapp
environment:
- DEBUG=false
- SEND_EMAILS=false
再编写一个新的development.yml文件,使用common.yml中的webapp服务进行扩展
# development.yml
web:
extends:
file: common.yml
service: webapp
ports:
- "8000:8000"
links:
- db
enviroment:
- DEBUG=true
db:
image: postgres
后者会自动继承common.yml中的webapp服务及环境变量定义
使用extends需要注意以下几点:
14、external_links指令
链接到docker-compose.yml外部的容器,甚至可以是非Compose管理的外部容器,参数格式跟links类似
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
15、extra_hosts指令
类似于Docker中的--add-host参数,指定额外的host名称映射信息
extra_hosts:
- "googledns:8.8.8.8"
- "dockerhub:52.1.157.61"
会在启动后的服务容器中 /etc/hosts 文件中添加如下两条条目
8.8.8.8 googledns
52.1.157.61 dockerhub
16、image指令
指定为镜像名称或镜像ID,如果镜像在本地不存在,Compose将会尝试拉取这个镜像
image: ubuntu
image: orchardup/postgresql
image: a4bc65fd
17、labels指令
为容器添加Docker元数据信息,例如可以为容器添加辅助说明信息
labels:
com.startupteam.description: "webapp for a startup team"
com.startupteam.department: "devops department"
com.startupteam.release: "rc3 for v1.0"
18、links指令
链接到其他服务中的容器,使用服务名称,或者使用"服务名称:服务别名"
links:
- db
- db:database
- redis
使用的别名将会自动在服务容器中的/etc/hosts里创建,所连接容器中相应的环境变量也将创建
19、log_driver指令
类似于Docker中的--log-driver参数,指定日志驱动参数,目前支持三种日志驱动类型
log_driver: "json-file"
log_driver: "syslog"
log_driver: "none"
20、log_opt指令
日志驱动的相关参数
log_driver: "syslog"
log_opt:
syslog-address: "tcp://192.168.0.42:123"
21、net指令
设置网络模式,参数类似于docker client的--net参数
net: "bridge"
net: "none"
net: "container:[name or id]"
net: "host"
22、pid指令
跟主机系统共享进程命名空间,打开该选项的容器之间,以及容器之间,以及容器和宿主机系统之间可以通过进程ID来相互访问和操作
pid "host"
23、ports指令
暴露端口信息,使用"宿主:容器"("HOST:CONTAINER")格式,或者仅仅指定容器的端口(宿主机将会随机选择端口)
ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001"
24、security_opt指令
指定容器模板标签label机制的默认属性(用户、角色、类型、级别等)
security_opt:
- label: user:USER
- label: role:ROLE
25、ulimits指令
指定容器的ulimits限制值,例如指定最大进程数为65535,指定文件句柄数为20000(软限制,应用可以随时修改,不能超过硬限制)和40000(系统硬限制,只能root用户提高)
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
26、volumes指令
数据卷所挂载路径设置,可以设置宿主机路径(HOST:CONTAINER)或加上访问模式(HOST:CONTAINER:ro),也支持相对路径
volumes:
# 容器中创建一个数据卷
- /var/lib/mysql
# 挂载一个主机目录作为数据卷(推荐方式)
- cache/:/tmp/cache
# 挂载一个本地主机文件作为数据卷(添加访问模式)
- ~/configs:/etc/configs/:ro
27、volumes_driver指令
较新版本的Docker支持数据卷的插件驱动,用户可以先使用第三方驱动创建一个数据卷,然后使用名称来访问它
volume_driver: mydriver
28、volumes_from指令
从另一个服务或容器挂载它的数据卷
volumes_from:
- service_name
- container_name
29、其他命令,基本跟docker run中对应参数的功能一致
| 命令 | 说明 | 实例 |
| cpuset | 指定使用CPU核数 | cpuset:0 |
| entrypoint | 指定服务容器启动后执行的命令,类似于Dockerfile的CMD | entrypoint:/code/entrypoint.sh |
| user | 指定容器中运行应用的用户名 | user: nginx |
| working_dir | 指定容器中工作目录 | working_dir: /code |
| domainname | 指定容器中搜索域名 | domainname: your_website.com |
| hostname | 指定容器中主机名 | hostname: test |
| mac_address | 指定容器中mac地址 | mac_address: 08-00-27-00-0C-0A |
| ipc | 指定容器 | ipc: host |
| men_limit | 指定容器中内存大小限制 | men_limit: 1g |
| menswap_limit | 指定容器中内存交换区大小限制 | menswap_limit: 1g |
| privileged | 允许容器中运行一些特权命令 | privileged: true |
| restart | 指定容器退出后的重启策略,对保持服务始终运行十分有效 | restart: always(始终重启) |
| read_only | 以只读模式挂载容器的root文件系统,不能对容器内容修改 | read_only: true |
| stdin_open | 打开标准输入,可以接受外部输入 | stdin_open: true |
| tty | 模拟一个假的远程控制台 | tty: true |
30、读取环境变量
Compose模板文件支持动态读取主机的系统环境变量
db:
image: "mongo:${MONGO_VERSION}"
上面的Compose文件将从运行它的环境中读取变量${MONGO_VERSION}的值,若MONGO_VERSION=3.2,那么docker-compose up则会启动一个mongo:3.2镜像的容器;如果MONGO_VERSION=2.8,docker-compose up则会启动一个mongo:2.8镜像的容器