官网文档地址 :https://docs.docker.com/compose/
一、介绍
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,可以使用 YML 文件来配置应用程序需要的所有服务。Docker Compose通过一条命令根据yml文件的定义去创建或管理多容器。
Compose 使用的三个步骤:
使用 Dockerfile 定义应用程序的环境。
使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
最后,执行 docker-compose up 命令来启动并运行整个应用程序。
compose文件格式版本与docker版本兼容性如下:
二、compose安装与卸载
1、安装
Linux 上我们可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:https://github.com/docker/compose/releases
。
curl -SL https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
chmod 755 /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose version
2、卸载
如果是二进制包方式安装的,删除二进制文件即可。
rm /usr/local/bin/docker-compose
如果是通过 pip 安装的,则执行如下命令即可删除。
pip uninstall docker-compose
三、YAML文件格式及编写
1、YAML文件格式
YAML是一种标记性语言,它可以很直观的展示数据序列化格式,可读性高。
类似于json数据描述语言,但是语法要比json简单很多。
YAML数据结构通过缩进来表示,连续的项目通过减号来表示,键值对用冒号分隔,数组用中括号[ ] 括起来,bash用花括号{ } 括起来。
2、YAML配置指令参考
version:指定本 yml 依从的 compose 哪个版本制定的
build:build 可以指定包含构建上下文的路径:
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"
target: prod
参数说明:
- context:上下文路径。指定 Dockerfile 文件所在的路径。
- dockerfile:指定构建镜像的 Dockerfile 文件名。没有该参数则默认文件名Dockerfile
- args:添加构建参数,这是只能在构建过程中访问的环境变量。
- labels:设置构建镜像的标签。
- target:多层构建,可以指定构建哪一层。
2.1 image:指定容器运行的镜像。可以是镜像仓库/标签或者镜像id(或者id的前一部分)
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd # 镜像id
2.2 container_name:指定自定义容器名称,而不是生成的默认名称。
container_name: nginx
由于Docker容器名称必须是唯一的,因此如果指定了自定义名称,则无法将服务扩展到多个容器。
2.3 ports:暴露容器端口,与-p相同,但是端口不能低于60。指定宿主机到容器的端口映射,或者只指定容器的端口,则表示映射到主机上的随机端口,一般采用主机:容器的形式来映射端口。
ports:
- "3000"
- "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"
2.4 expose:暴露端口,但不映射到宿主机,只被连接的服务访问。仅可以指定内部端口为参数:
expose:
- "3000"
- "8000"
2.5 extra_hosts:添加主机名映射。类似 docker client –add-host。
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
以上会在此服务的内部容器中 /etc/hosts
创建一个具有 ip 地址和主机名的映射关系:
162.242.195.82 somehost
50.31.209.229 otherhost
2.6 healthcheck:用于检测 docker 服务是否健康运行。
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序
interval: 1m30s # 设置检测间隔
timeout: 10s # 设置检测超时时间
retries: 3 # 设置重试次数
start_period: 40s # 启动后,多少秒开始启动检测程序
2.7 deploy:指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用。
version: "3.7"
services:
redis:
image: redis:alpine
deploy:
mode:replicated
replicas: 6
endpoint_mode: dnsrr
labels:
description: "This redis service label"
resources:
limits:
cpus: '0.50'
memory: 50M
reservations:
cpus: '0.25'
memory: 20M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
可以选参数:
- condition:可选 none,on-failure 或者 any(默认值:any)。
- delay:设置多久之后重启(默认值:0)。
- max_attempts:尝试重新启动容器的次数,超出次数,则不再尝试(默认值:一直重试)。
- window:设置容器重启超时时间(默认值:0)。
- replicated:复制服务,复制指定服务到集群的机器上。
- global:全局服务,服务将部署至集群的每个节点。
2.8 endpoint_mode:访问集群服务的方式。
endpoint_mode: vip
# Docker 集群服务一个对外的虚拟 ip。所有的请求都会通过这个虚拟 ip 到达集群服务内部的机器。
endpoint_mode: dnsrr
# DNS 轮询(DNSRR)。所有的请求会自动轮询获取到集群 ip 列表中的一个 ip 地址。
2.9 labels:在服务上设置标签。可以用容器上的 labels(跟 deploy 同级的配置) 覆盖 deploy 下的 labels。
2.10 mode:指定服务提供的模式。
2.11 replicas:mode 为 replicated 时,需要使用此参数配置具体运行的节点数量。
2.12 resources:配置服务器资源使用的限制,例如上例子,配置 redis 集群运行需要的 cpu 的百分比 和 内存的占用。避免占用资源过高出现异常。
2.13 restart_policy:配置如何在退出容器时重新启动容器。
- condition:可选 none,on-failure 或者 any(默认值:any)。
- delay:设置多久之后重启(默认值:0)。
- max_attempts:尝试重新启动容器的次数,超出次数,则不再尝试(默认值:一直重试)。
- window:设置容器重启超时时间(默认值:0)。
2.14 rollback_config:配置在更新失败的情况下应如何回滚服务。
- parallelism:一次要回滚的容器数。如果设置为0,则所有容器将同时回滚。
- delay:每个容器组回滚之间等待的时间(默认为0s)。
- failure_action:如果回滚失败,该怎么办。其中一个 continue 或者 pause(默认pause)。
- monitor:每个容器更新后,持续观察是否失败了的时间 (ns|us|ms|s|m|h)(默认为0s)。
- max_failure_ratio:在回滚期间可以容忍的故障率(默认为0)。
- order:回滚期间的操作顺序。其中一个 stop-first(串行回滚),或者 start-first(并行回滚)(默认 stop-first )。
2.15 update_config:配置应如何更新服务,对于配置滚动更新很有用。
- parallelism:一次更新的容器数。
- delay:在更新一组容器之间等待的时间。
- failure_action:如果更新失败,该怎么办。其中一个 continue,rollback 或者pause (默认:pause)。
- monitor:每个容器更新后,持续观察是否失败了的时间 (ns|us|ms|s|m|h)(默认为0s)。
- max_failure_ratio:在更新过程中可以容忍的故障率。
- order:回滚期间的操作顺序。其中一个 stop-first(串行回滚),或者 start-first(并行回滚)(默认stop-first)。
2.16 depends_on:设置依赖关系。docker-compose up 以依赖性顺序启动服务。
2.17 devices:指定设备映射列表。
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"
2.18 volumes:将主机的数据卷或文件挂载到容器里。
version: "3.7"
services:
mysql:
image: mysql/mysql-server:5.7.28
container_name: mysql
ports:
- "3306:3306"
volumes:
- ./services/mysql5/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro
- ./services/mysql5:/var/lib/mysql/:rw
- ./logs/mysql5:/var/log/mysql/:rw
2.19 environment:添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。
mysql:
image: mysql/mysql-server:5.7.28
container_name: mysql
ports:
- "3306:3306"
volumes:
- ./services/mysql5/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro
- ./services/mysql5:/var/lib/mysql/:rw
- ./logs/mysql5:/var/log/mysql/:rw
restart: always
networks:
- default
environment:
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_ROOT_HOST: "%"
2.20 env_file:从文件添加环境变量。可以是单个值或列表的多个值。
env_file: .env
也可以是列表格式:
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
2.21 command:覆盖容器启动的默认命令。
#command: bundle exec thin -p 3000
command: ["bundle", "exec", "thin", "-p", "3000"]
2.22 links:链接到另一个服务中的容器。请指定服务名称和链接别名(SERVICE:ALIAS),或者仅指定服务名称。
web:
links:
- db
- db:database
- redis
在当前的web服务的容器中可以通过链接的db服务的别名database访问db容器中的数据库应用,如果没有指定别名,则可直接使用服务名访问。links也可以起到和depends_on相似的功能,即定义服务之间的依赖关系,从而确定服务启动的顺序。
2.23 networks:网络类型,可指定容器运行的网络类型。使用时引用顶级 networks 下的条目 。
#指定对应的网络
version: "3"
services:
mysql:
image: mysql/mysql-server:5.7.28
container_name: mysql
ports:
- "3306:3306"
volumes:
- ./services/mysql5/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro
- ./services/mysql5:/var/lib/mysql/:rw
- ./logs/mysql5:/var/log/mysql/:rw
restart: always
networks:
- default
environment:
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_ROOT_HOST: "%"
networks:
default:
driver: bridge
ipam:
driver: default
# 解除下面的注释可以设置网段,用于nginx等容器固定容器IP
#config:
# - subnet: 10.0.0.0/24
2.24 restart:重启策略。
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
注:swarm 集群模式,请改用 restart_policy。
no:是默认的重启策略,在任何情况下都不会重启容器。
always:容器总是重新启动。
on-failure:在容器非正常退出时(退出状态非0),才会重启容器。
unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
2.25 pid:将PID模式设置为主机PID模式。这就打开了容器与主机操作系统之间的共享PID地址空间。使用此标志启动的容器将能够访问和操作裸机的命名空间中的其他容器,反之亦然。即打开该选项的容器可以相互通过进程 ID 来访问和操作。
pid: "host"
2.26 dns:配置 DNS 服务器。可以是一个值,也可以是一个列表。
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
2.27 dns_search:自定义 DNS 搜索域。可以是单个值或列表。
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com
2.28 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
2.29 logging:服务的日志记录配置。
driver:指定服务容器的日志记录驱动程序,默认值为json-file。有以下三个选项
driver: "json-file"
driver: "syslog"
driver: "none"
仅在 json-file 驱动程序下,可以使用以下参数,限制日志得数量和大小。
logging:
driver: json-file
options:
max-size: "200k" # 单个文件大小为200k
max-file: "10" # 最多10个文件
当达到文件限制上限,会自动删除旧得文件。syslog 驱动程序下,可以使用 syslog-address 指定日志接收地址。
logging:
driver: syslog
options:
syslog-address: "tcp://192.168.0.42:123"
2.30 secrets:存储敏感数据,例如密码:
version: "3.1"
services:
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secret
secrets:
- my_secret
secrets:
my_secret:
file: ./my_secret.txt
2.31 security_opt:修改容器默认的 schema 标签。
security-opt:
- label:user:USER # 设置容器的用户标签
- label:role:ROLE # 设置容器的角色标签
- label:type:TYPE # 设置容器的安全策略标签
- label:level:LEVEL # 设置容器的安全等级标签
2.32 stop_grace_period:指定在容器无法处理 SIGTERM (或者任何 stop_signal 的信号),等待多久后发送 SIGKILL 信号关闭容器。
stop_grace_period: 1s # 等待 1 秒
stop_grace_period: 1m30s # 等待 1 分 30 秒
默认的等待时间是 10 秒。
2.33 tmpfs:在容器内安装一个临时文件系统。可以是单个值或列表的多个值。
tmpfs: /run
tmpfs:
- /run
- /tmp
2.34 ulimits:覆盖容器默认的 ulimit。
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
2.35 sysctls:设置容器中的内核参数,可以使用数组或字典格式。
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0
2.36 stop_signal:设置停止容器的替代信号。默认情况下使用 SIGTERM 。
以下示例,使用 SIGUSR1 替代信号 SIGTERM 来停止容器。
stop_signal: SIGUSR1
3、YAML格式的注意事项
不支持制表符tab键缩进,只能使用空格缩进
通常开头缩进2个空格
字符后缩进1个空格,如冒号【:】、逗号【,】、横杠【-】
用#号表示注释
如果包含特殊字符用单引号【’ '】引起来作为普通字符,如果用双引号【" “】表示特殊字符本身的意思,
布尔值必须用【” "】括起来
YAML区分大小写
四、compose使用
通过docker-compose构建一个在docker中运行的redis容器
1、编辑配置文件redis.conf
[root@localhost ~]# mkdir -p /redis/{data,logs}
[root@localhost ~]# chmod -R 777 /redis
[root@localhost ~]# cd /redis
[root@localhost redis]# vim redis.conf
redis.conf配置文件添加内容如下:
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel verbose
logfile /logs/redis.log
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
# The filename where to dump the DB
dbfilename dump.rdb
dir ./
#
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
# requirepass foobared
requirepass 123456
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly yes
# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof"
# appendfsync always
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
2、编写Dockerfile
[root@localhost redis]# cat Dockerfile
FRPM redis:alpine
MAINTAINER user<xxx@qq.com>
COPY redis.conf /usr/local/etc/redis/redis.conf
EXPOSE 6379
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
3、创建 docker-compose.yml
[root@localhost redis]# cat docker-compose.yml
version: "3"
services:
redis:
image: redis:alpine
container_name: redis
privileged: true
ports:
- "6379:6379"
environment:
- REDIS_PASSWORD=123456
volumes:
- ./redis.conf:/usr/local/etc/redis/redis.conf
- ./data:/data/:rw
- ./logs:/logs
restart: always
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
4、使用 compose 命令构建和运行您的应用
[root@localhost redis]# docker-compose up -d
5、查看redis容器
[root@localhost redis]# docker ps -a
6、进入redis服务,并登录客户端测试
[root@localhost redis]# docker exec -it redis /bin/sh
# redis-cli
127.0.0.1:6379> keys *
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth '123456'
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set name lin
OK