Doker和Compose 兼容性矩阵:
官方文档
提示:您可以使用此文件的扩展名为
.ym
l或.yanl
扩展名
文件结构说明
从上面的示例模板文件中可以看出,*的配置项有:
ersion 定义了版本信息
services 定义了服务的配置信息
networks 定义了网络信息,提供给 services 中的 具体容器使用
volumes 定义了卷信息,提供给 services 中的 具体容器使用
关于*services
配置参考
1.container_name
指定容器名称。默认将会使用项目名称_服务名称_序号 这样的格式。
1 | container_name: docker-web-container
示例
version: "3.8"
services:
web5:
image: nginx
container_name: docker-web-container
注意: 指定容器名称后,该服务将无法进行扩展(scale),因为 Docker 不允许多个容器具有相同的名称。
2.labels
注意每个服务都必须通过 image 指令指定镜像或 build 指令(需要 Dockerfile)等来自动构建生成镜像。
如果使用 build 指令,那么在 Dockerfile 中设置的选项(例如:CMD, EXPOSE, VOLUME, ENV 等)
将会自动被获取,无需在 docker-compose.yml 中再次设置。
下面分别介绍几个指令的用法:
3.build
指定 Dockerfile 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。
类似于命令行的 docker build .
version:"3"
services:
webapp:
build: . #当前这个路径
示例:
1 | mkdir build
2 | cat Docker-compose.yml
version:"3"
services:
webapp:
build: .
3 | cat Dockerfile
From nginx
COPY ./index.html /usr/share/nginx/html/index.html
4 | echo 哈哈哈哈哈 > index.html # 内容只是为了显示效果
5 | docker-compose up -d # 构建这个镜像
你也可以使用 context 指令指定 Dockerfile 所在文件夹的路径。
同时使用 dockerfile 指令指定 Dockerfile 文件名。
version: '3'
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
4.image
指定为镜像名称或镜像 ID。如果镜像在本地不存在,Compose
将会尝试拉取这个镜像。
1 | image: ubuntu
2 | image: nginx:alpine
3 | image: mysql/mysql-server:5.7
示例:
1 | mkdir image
2 | cd image/
3 | cat docker-compose.yml
version: "3.8"
services:
sky1:
image: nginx # 本地容器存在的镜像
4 | docker-compose up -d
如果同时指定了 image
和 build
, image
不在具有单独使用它的意义,而是指定了目前要构建的镜像的名称。 也就是说 Compose
会使用 build
指令中指定的 Dockerfilel
构建的镜像,之后构建的镜像名称使用 image
中指定的名字 webapp:tag
命名。
1 | build: ./dir
2 | image: webapp:tag
示例:
1 | mkdir image
2 | cd image/
3 | cat Dockerfile
FROM nginx
4 | cat docker-compose.yml
version: "3.8"
services:
sky1:
image: nginx # 本地容器存在的镜像
sky2:
build: .
image: webapp:1.0
4 | docker-compose up -d
以上这个示例 构建的镜像是image设置的镜像名称!
5.command
使用command 可以覆盖容器启动后默认执行的命令
1 | command: bundle exec thin -p 3000
也可以写成类似Dockerfile中的格式
1 | command: [bundle, exec, thin, -p, 3000]
示例:
1 | mkdir command
2 | cd command/
3 | cat docker-compose.yml
version: "3"
services:
app1:
image:nginx
command: /bin/sh
container_name: nginx-sh
app2:
image: nginx
container_name: nginx-off
4 | docker run -d nginx /bin/sh # 第一种方法运行
5 | docker run -d nginx # 第二种方法运行
6 | docker-compose up -d # 启动docker-compose的yml文件
结果如图所示
6.depends_on
解决容器的依赖、启动先后的问题。以下以下例子中会先启动容器 db
和 redis
再启动 web
version: '3'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
注意: web服务不会等待redis 和db 【完全启动】 之后才启动
实质上规定的是启动容器的顺序,不会自动检测出
自己所依赖的容器是否真正启动完成
6.environment
设置环境变量。你可以使用数组或字典两种格式。
只给定名称的变量会自动获取运行 Compose 主机上对应变量的值,可以用来防止泄露不必要的数据
environment:
RACK_ENV: development
SESSION_SECRET:
environment:
- RACK_ENV=development
- SESSION_SECRET
示例
1 | mkdir command
2 | cd command/
3 | cat docker-compose.yml
version: "3.8"
services:
h2:
image: alpine
stdin_open: true
tty: true
environment:
user: tao
TEST:
在自己的服务器中,给TEST
赋个值
1 | TEST=123456789
2 | echo $TEST
3 | docker-compose up -d
4 | docker-compose exec h2 sh # 进入容器
5 | echo $TEST # 这样会显示赋的值
在服务器主机上,声明TEST
为环境变量
1 | export TEST
2 | docker-compose up -d
如果变量名称或者值中用到 true|false,yes|no
等表达 布尔 含义的词汇,最好放到引号里,避免 YAML
自动解析某些内容为对应的布尔语义。这些特定词汇,包括
y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF
7.expose
暴露端口,但不映射到宿主机,只被其他容器连接到此容器时使用。
仅可以指定容器内部的端口为参数
expose:
- "3000"
- "8000"
8.ports
映射端口信息
使用:
宿主端口: 容器端口(即: HOST:CONTAINER)的格式,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。
ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001"
注意:当使用HOST:CONTAINER 格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 YAML 会自动解析 xx:yy 这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。
示例
1 | mkdir ports
2 | cd ports
3 | cat doker-compose.yml
version: "3.8"
services:
web2
image: nginx
ports:
- "9000:80" # docker run -p 9000:80
4 | docker-compose up -d
在主机上:直接测试
1 | curl 127.0.0.1:9000
9.extra_hosts
类似Docker中的 --add-host参数,指定额外的host 名称映射信息。
extra_hosts:
- "googledns:8.8.8.8"
- "dockerhub:52.1.157.61"
在启动后的服务容器中/etc/hosts文件中添加如下两条条目
1 | 8.8.8.8 googledns
2 | 2.1.157.61 dockerhub
示例
1 | mkdir extra_hosts
2 | cd extra_hosts
3 | cat docker-compose.yml
version: "3.8"
services:
web2
image: nginx
ports:
- "8500:80"
extra_hosts:
- "web3:192.168.64.5"
- "www.taotao.com:192.168.64.55"
4 | docker-compose up -d
5 | docker-compose exec web2 sh(登录容器)
6 | cat /etc/hosts (此命令会看到两个ip会添加在hosts文件中)
10.networks
要加入的网络,使用*networks 定义下的项目
services:
some-service:
networks:
- some-network
- other-network
networks:
some-network:
other-network:
示例
1 | mkdir network
2 | cd network/
3 | cat docker-compose.yml
version: "3.8"
services:
web5:
image: nginx
ports:
- "8530:80"
networks: #自定义的网络名称
- h5-net
web4:
image: centos
tty: true
stdin_open: true
networks:
- h5-net #docker run --network=h5-net
networks: #docker network create
h5-net:
4 | docker-compose up -d
5 | docker network inspect network_h5-net # 查看network里的web5和web4
6 | docker-compose exec web4 bash
7 | ping web4
案例:
1 | mkdir web-db-redis
2 | cd web-db-redis/
3 | cat docker-compose.yml
version: "3.8"
services:
web2:
image: nginx
networks:
- net-web
- net-db
mysql:
image:
networks:
- net-db
redis:
image: redis:alpine
networks:
- net-db
networks:
net-db:
net-web:
4 | docker-compose up -d
5 | docker-compose ps # 查看容器
6 | docker-compose exec web2 sh 登录容器
10.1 指定IPv4
和IPv6
version: "2.4"
services:
app:
image: busybox
command: ifconfig
networks:
app_net:
ipv4_address: 172.16.238.10
ipv6_address: 2001:3984:3989::10
networks:
app_net:
driver: bridge
enable_ipv6: true
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
gateway: 172.16.238.1
- subnet: 2001:3984:3989::/64
gateway: 2001:3984:3989::1
修改上方 的`docker-composversion: "2.4"
services:
app:
image: busybox
command: ifconfig
networks:
app_net:
ipv4_address: 172.16.238.10
ipv6_address: 2001:3984:3989::10
networks:
app_net:
driver: bridge
enable_ipv6: true
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
gateway: 172.16.238.1
- subnet: 2001:3984:3989::/64
gateway: 2001:3984:3989::1
指定自定义IPAM配置。这是一个具有多个属性的对象,每个属性都是可选的:
driver:自定义IPAM驱动程序,而不是默认驱动程序。 config:具有零个或多个配置块的列表,每个配置块包含以下任一键:
subnet:CIDR格式的子网, 就是这个网络的网段 ip_range:从中分配容器IP的IP范围
gateway:主子网的IPv4或IPv6网关
aux_addresses:网络驱动程序使用的辅助IPv4或IPv6地址,作为从主机名到IP的映射
options:特定于驱动程序的选项作为键值映射。
示例
1 | cat docker-compose.yml
version: "3.8"
services:
web5:
image: nginx
# (nginx)这个镜像不支持 直接查看ip 需使用docker inspect 容器名
tty: true
stdin_open: true
container_name: tao
ports:
- "8530:80"
networks: #自定义的网络名称
h5-net:
ipv4_address: 172.16.238.10
web4:
image: centos
tty: true
stdin_open: true
networks:
- h5-net #docker run --network=h5-net
networks: #docker network create
h5-net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
gateway: 172.16.238.1
1 | docker-compose down # 删除上面network创建的容器
2 | docker-compose up -d
3 | docker-compose exec web4 ip a # 查看web4的ip
4 | docker inspect tao # 查看web5 的ip
第二种方法:
1 | cat docker-compose.yml
vim docker-compose.yml
version: "3.8"
services:
web5:
image: centos
# (centos)这个镜像支持 直接查看ip
tty: true
stdin_open: true
container_name: tao
ports:
- "8530:80"
networks: #自定义的网络名称
h5-net:
ipv4_address: 172.16.238.10
web4:
image: centos
tty: true
stdin_open: true
networks:
- h5-net #docker run --network=h5-net
networks: #docker network create
h5-net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
gateway: 172.16.238.1
1 | docker-compose down
2 | docker-compose up -d
3 | docker-compose exec web5 ip a # 这种是基于centos的镜像 才可以直接查看ip
10.2使用现有网络
如果您希望容器加入现有网络,请使用以下external选项
version: "3"
servers:
host1:
image: centos
stdin_open: true
tty: true
networks:
# 此项目中的服务使用的默认网络,此网络不会被创建
# 实际会使用 my-pre-existing-network
default:
external:
name: my-pre-existing-network
这种情况下,Compose不会尝试创建名为 [projectname]_default
的网络,而是查找名为 my-pre-existing-network
的网络,并将应用程序的容器连接到该网络。
也可以把默认 default
网络改成其他的名称,比如
version: "3.8"
services:
host1:
image: centos
stdin_open: true
tty: true
networks:
shark:
networks:
tao:
external:
name: my-pre-existing-network
示例:
1 | mkdir net-exnet
2 | cd net-exnet/
3 | cat docker-compose.yml
version: "3.8"
services:
h2:
image:centos
stdin_open: true
tty: true
networks:
default:
external:
name: networks_h5-net
4 | docker-compose exec h2 bash # 登录h2 这个容器
5 | ip a
11.aliases
网络上此服务的别名(备用主机名)。同一网络上的其他容器可以使用服务名称或此别名连接到其中一个服务的容器。
由于aliases是网络范围的,因此相同的服务可以在不同的网络上具有不同的别名。
一般格式如下所示。
services:
some-service:
networks:
some-network:
aliases:
- alias1
other-network:
aliases:
- alias2
示例
1 | mkdir aliases
2 | cd aliases
3 | cat docker-compose.yml
version: "3.8"
services:
h2:
image: centos
stdin_open: true
tty: true
networks:
n-1:
aliases:
- h1
n-2:
aliases:
- hh
h3:
image: centos
stdin_open: true
networks:
n-1:
h4:
image: centos
stdin_open: true
networks:
n-2:
networks:
n-1:
n-2:
4 | docker-compose exec h3 ping h2 别名ping
12.healthcheck
通过命令检查容器是否健康运行。
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
示例
1 | mkdir healthcheck
2 | cd healthcheck/
3 | cat docker-compose.yml
version: "3"
services:
web1:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 5s
timeout: 3s
retries: 3
4 | docker-compose up -d
5 | docker-compose ps
13.volumes
1.volumes
数据卷所挂载路径设置。可以设置宿主机路径 (HOST:CONTAINER) 或加*问模式 (HOST:CONTAINER:ro)
该指令中路径支持相对路径。
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro
卷的 bind
和 volume
的混合使用
version: "3.2"
services:
web:
image: nginx:alpine
volumes:
# 卷 (volume)
- type: volume
source: mydata
target: /data
volume:
nocopy: true
# 挂载 (bind)
- type: bind
source: ./static
target: /opt/app/static
db:
image: postgres:latest
volumes:
- "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock"
- "dbdata:/var/lib/postgresql/data"
volumes:
mydata:
dbdata:
示例 (这个直接修改网页是不及时生效的)
1 | mkdir volume
2 | cd volume/
3 | mkdir nginx
4 | mkdir -p nginx/conf
5 | echo haha > nginx/index.html
5 | cat docker-compose.yml
文件内容
version: "3.8"
services:
web2:
image: nginx
volumes:
- type: bind # bind volume tmpfile
source: ./nginx/index.html
target: /usr/share/nginx/html/index.html
- type: bind
source: ./nginx/conf/default.conf
target: /etc/nginx/conf.d/default.conf
1 | docker exec -it nginx sh # 登录nginx容器 nginx镜像本地本地存在的!
2 | cd /etc/nginx/conf.d/ #将容器内的这个目录下的文件查看一下
3 | docker cp id:/etc/nginx/conf.d/default.conf . # 这个id是nginx的镜像id,拷贝到当前目录下
4 | mv default.conf nginx/conf/
5 | docker-compose up -d
6 | curl 127.0.0.1:8090 # 这步是在容器内执行 查看
6 | docker-compose exec web2 curl localhost:8090 # 这个是在服务器上直接执行的 交互式
示例2:(这个直接修改网页是及时生效的)
在上面这个环境下执行 直接修改docker-compose.yml
文件
1 | cat docker-compose.yml
文件内容如下
version: "3"
services:
web2:
image: nginx:alpine
volumes:
- type: bind # bind volume tmpfile
source: ./nginx/
target: /usr/share/nginx/html/
- type: bind
source: ./nginx/conf/default.conf
target: /etc/nginx/conf.d/default.conf
1 | docker-compose exec web2 curl 127.0.0.1:8090
# 直接访问 同时也可以修改index.html文件继续执行此命令 然后持续观察页面结果
以目录的方式挂载
1 | cat docker-compose.yml
文件内容如下
version: "3"
services:
web2:
image: nginx:alpine
volumes:
- type: bind # bind volume tmpfile
source: ./nginx/
target: /usr/share/nginx/html/
- type: bind
source: ./nginx/conf/
target: /etc/nginx/conf.d/
停止容器,重新启动
1 | docker-compose down -v
2 | docker-compose up -d
3 | cd nginx/conf
4 | vim default.conf # 修改端口
5 | docker-compose exec web2 sh # 登录容器
6 | cat etc/nginx/conf.d/default.conf # 查看修改的内容是否同步
7 | docker-compose exec web2 curl localhost:8000 # 查看结果
8 | docker-compose down # 重启启动 执行第7步操作去继续查看结果
14.sysctls
+ulimits
sysctls
配置容器内核参数
sysctls:
net.core.somaxconn: 1024
net.ipv4.tcp_syncookies: 0
sysctls:
- net.core.somaxconn=1024
- net.ipv4.tcp_syncookies=0
ulimits
指定容器的ulimits限制值
例如,指定最大进程数为 65535,指定文件句柄数为 20000(软限制,应用可以随时修改,不能超过硬限制) 和 40000(系统硬限制,只能 root 用户提高)。
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
综合示例
1 | mkdir ysctls-ulimit
2 | cd ysctls-ulimit
3 | cat docker-compose.yml
文件内容如下
version: "3"
services:
web2:
image: nginx
sysctls:
net.core.somaxconn: 1024
ulimits:
nproc: 65535
nofile:
soft: 20000
hard: 40000
启动容器,进入容器,查看
1 | docker-compose up d
2 | docker-compose exec web2 bash
3 | ulimit -a